Compare commits

...

1095 Commits

Author SHA1 Message Date
Spring Buildmaster a957543672 Release version 4.3.22.RELEASE 2019-01-09 09:00:42 +00:00
Juergen Hoeller a8f540ae8c Restored original log4j.properties file reference in 4.3.x branch 2019-01-08 21:18:09 +01:00
Juergen Hoeller 9767165c8d Upgrade to Tomcat 8.5.37 2019-01-08 20:58:23 +01:00
Juergen Hoeller 7be0aa0de5 Polishing 2019-01-08 20:58:10 +01:00
Juergen Hoeller e714fc533a DefaultListableBeanFactory checks for pre-converted Optional wrappers
Issue: SPR-17607
2019-01-08 20:55:55 +01:00
Juergen Hoeller c02446c5a8 Relaxed position assertion (for overflows in large inline maps)
Issue: SPR-17605

(cherry picked from commit b2756f5bd2)
2019-01-08 20:55:23 +01:00
Juergen Hoeller 21baa7287b Consistent support for EnumSet subclasses in CollectionFactory
Issue: SPR-17619

(cherry picked from commit 31a24720a6)
2019-01-08 20:55:10 +01:00
Sam Brannen 3c7887c2ae Provide external links to JUnit in published Javadoc API 2019-01-08 16:24:17 +01:00
Michel Schudel 21d3bf8db4 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:07:41 +01:00
Juergen Hoeller ce05a5b5c0 Polishing 2018-12-12 13:04:59 +01:00
Juergen Hoeller b00f98fccf Revised SimpleEvaluationContext example
Issue: SPR-17581
2018-12-12 13:04:51 +01:00
Juergen Hoeller 7ff1b0e01d Clarified VfsResource constructor
Issue: SPR-17563

(cherry picked from commit 50e5bdb813)
2018-12-04 22:35:04 +01:00
Juergen Hoeller 792991a88b Cleanup after unexpected exception from external delegation call
Issue: SPR-17559

(cherry picked from commit c024bdcc6f)
2018-12-04 02:43:52 +01:00
Juergen Hoeller b8480ea011 Polishing 2018-12-04 01:21:16 +01:00
Juergen Hoeller bf9043c737 Upgrade to POI 3.17 (and Netty 4.1.32)
Issue: SPR-17385
2018-12-04 01:20:57 +01:00
Juergen Hoeller 4decaa2da6 Revised section on custom BeanPostProcessors
Issue: SPR-17556
2018-12-04 01:20:28 +01:00
Juergen Hoeller 9d504c8e1d Avoid log statements between resource opening and returning
Issue: SPR-17559

(cherry picked from commit 7854b7ac40)
2018-12-04 01:20:19 +01:00
Juergen Hoeller 191a2d3f25 JavaMailSenderImpl calls sendMessage with empty array instead of null
Issue: SPR-17540

(cherry picked from commit 16e9b83d43)
2018-12-04 01:20:11 +01:00
Spring Buildmaster a46a437299 Next Development Version 2018-11-27 07:40:08 +00:00
Juergen Hoeller 9600e015b7 Revised alias definition example in reference documentation
Issue: SPR-17536
2018-11-25 22:30:41 +01:00
Juergen Hoeller e9f7c357b7 ResolvableType-based matching consistently respects generic factory method return type (even for pre-initialized raw singleton instance)
Issue: SPR-17524

(cherry picked from commit ebbe14c363)
2018-11-25 22:30:33 +01:00
Juergen Hoeller cf8479c8ab Upgrade to Tomcat 8.5.35, Netty 4.1.31, Gson 2.8.5, Jackson 2.8.11.3
Also includes Apache HttpClient 4.5.6 and HttpAsyncClient 4.1.4.
2018-11-24 14:23:55 +01:00
Juergen Hoeller 1c1b94285d DefaultResponseErrorHandler detects non-standard error code as well
Issue: SPR-17439
2018-11-23 20:21:30 +01:00
Juergen Hoeller 85b5c5a134 Polishing 2018-11-22 20:20:36 +01:00
Juergen Hoeller ed9afa3686 FastByteArrayOutputStream.read byte-to-int conversion
Issue: SPR-17492
2018-11-22 20:20:26 +01:00
Juergen Hoeller 22f4b1ce6b SerializedBeanFactoryReference falls back to dummy with specific id
Issue: SPR-17508

(cherry picked from commit f5aeb81473)
2018-11-22 20:20:14 +01:00
Rossen Stoyanchev abacc6d29e BEST_MATCHING_HANDLER_ATTRIBUTE for spring-webmvc
Issue: SPR-17518
2018-11-21 09:38:59 -05:00
Juergen Hoeller 8d668acbb4 Up-to-date version and link in ASM/CGLIB/Objenesis package javadoc
Issue: SPR-16405
Issue: SPR-15600
2018-11-08 17:12:05 +01:00
Juergen Hoeller 4f5ae22a52 Consistently return empty array in case of empty batch arguments
Issue: SPR-17476

(cherry picked from commit 362c59c310)
2018-11-08 14:09:44 +01:00
Juergen Hoeller 8f1f36d6fb Upgrade to Animal Sniffer 1.17, Tiles 3.0.8, Tomcat 8.5.34 2018-11-05 23:52:07 +01:00
Juergen Hoeller 79e7ba71bb Polishing 2018-11-05 23:51:54 +01:00
Juergen Hoeller f002ebd976 Explicit notes on class/method-level semantics in class hierarchies
Issue: SPR-17445

(cherry picked from commit ea3250c8d6)
2018-11-05 23:51:48 +01:00
Juergen Hoeller b43e7335b8 Polishing 2018-10-27 16:14:53 +02:00
Juergen Hoeller 6711515ef5 Exclude FactoryBean implementation methods on CGLIB proxies as well
Issue: SPR-17374

(cherry picked from commit dc1e3b4628)
2018-10-27 16:14:31 +02:00
Juergen Hoeller 47ca7b39a2 Polishing 2018-10-24 22:10:05 +02:00
Juergen Hoeller 448182fa5c ConfigurableWebApplicationContext needed for contextClass parameter
Issue: SPR-17414
2018-10-24 22:06:48 +02:00
Juergen Hoeller 46bc145196 SpringFactoriesLoader tolerates whitespace around class names
Issue: SPR-17413

(cherry picked from commit dd2ce20687)
2018-10-24 22:06:35 +02:00
Juergen Hoeller 3a4fd2c832 Avoid stacktrace if root resource is not resolvable in file system
Issue: SPR-17417

(cherry picked from commit 83a54dba7e)
2018-10-24 22:06:26 +02:00
Juergen Hoeller cd664673ed Clarify FactoryBean initialization effect in getBeanNamesForAnnotation
Issue: SPR-17392

(cherry picked from commit da23505e94)
2018-10-24 22:06:19 +02:00
Juergen Hoeller a3bdeb2c53 Clarify destruction order effect in @DependsOn annotation javadoc
Issue: SPR-17384

(cherry picked from commit 00b7782b5f)
2018-10-24 22:06:11 +02:00
Brian Clozel 9efe37e649 Fix ResourceUrlEncodingFilter lifecycle
Prior to this commit, the `ResourceUrlEncodingFilter` would wrap the
response and keep a reference to the request. When
`HttpServletResponse.encodeURL` is later called during view rendering,
the filter looks at the request and extracts context mapping information
in order to resolve resource paths in views.

This approach is flawed, when the filter is used with JSPs - if the
request is forwarded to the container by the `InternalResourceView`,
the request information is overwritten by the container. When the view
is being rendered, the information available in the request is outdated
and does not allow to correctly compute that context mapping
information.

This commit ensures that that information is being extracted from the
request as soon as the `ResourceUrlProvider` is set as a request
attribute.

Issue: SPR-17421
(Cherry-picked from cf25efc7d3)
2018-10-24 21:20:29 +02:00
Rossen Stoyanchev 8e980d9a63 Restore log level for resolved exceptions
The fix for SPR-17178 switched from debug to warn level warning for
all sub-classes of AbstractHandlerExceptionResolver where the request
concerned the DefaultHandlerExceptionResolver only.

This commit restores the original DEBUG level logging that was in
AbstractHandlerExceptionResolver from before SPR-17178. In addition
DefaultHandlerExceptionResolver registers a warnLogCategory by default
which enables warn logging and hence fulfilling the original goal
for SPR-17178.

Issue: SPR-17383
2018-10-22 12:22:18 -04:00
Spring Buildmaster f7c625cfcc Next Development Version 2018-10-15 08:48:23 +00:00
Rossen Stoyanchev 044772641d HttpRange validates requested ranges
Issue: SPR-17318
2018-10-14 23:03:34 -04:00
Juergen Hoeller d15abfdb3f Revert support for concurrent BeanPostProcessor registration in 4.3.x
Issue: SPR-17286
2018-10-14 22:12:35 +02:00
Juergen Hoeller ebe3c270cb MethodValidationInterceptor excludes FactoryBean metadata methods
Issue: SPR-17374

(cherry picked from commit 5f2d47a17e)
2018-10-14 22:12:24 +02:00
Juergen Hoeller 6c9c8efc38 Polishing 2018-10-10 00:32:07 +02:00
Juergen Hoeller b53995b5d4 Resource.lastModified() propagates 0 value if target resource exists
Issue: SPR-17320
2018-10-10 00:31:49 +02:00
Rossen Stoyanchev 547b841172 Oops, add uncommitted change for last commit. 2018-10-09 12:23:25 -04:00
Rossen Stoyanchev f61f6f2ef0 More defensive check for MockAsyncContext
Avoid automatically unwrapping the request in TestDispatcherServlet,
if we find the MockAsyncContext.

Issue: SPR-17353
2018-10-09 12:00:36 -04:00
Juergen Hoeller de1139e6a0 Polishing 2018-09-29 17:55:10 +02:00
Juergen Hoeller e978f90a19 MockHttpServletRequest allows for removing registered header entries
Issue: SPR-17295
2018-09-29 17:55:03 +02:00
Juergen Hoeller ebd92fec6d Revised javadoc for up-to-date constructor autowiring semantics
Issue: SPR-17299

(cherry picked from commit 333e327289)
2018-09-29 17:54:54 +02:00
Juergen Hoeller fa06faa3ec Use local copy set into volatile field instead of CopyOnWriteArrayList
Keep supporting legacy usage of Iterator.remove on getBeanPostProcessors result List in AbstractBeanFactoryBasedTargetSourceCreator and ScriptFactoryPostProcessor (and similarly designed integrations).

Issue: SPR-17286
2018-09-18 23:32:14 +02:00
Juergen Hoeller e94624d439 Polishing 2018-09-18 22:09:07 +02:00
Juergen Hoeller 0d1bf52122 Defensively expect concurrent registration of BeanPostProcessors
Declaring beanPostProcessors (and also embeddedValueResolvers) as CopyOnWriteArrayList prevents ConcurrentModificationExceptions in case of concurrent registration/access attempts.

Issue: SPR-17286
2018-09-18 22:09:01 +02:00
Juergen Hoeller ec1aa5c6ea Polishing 2018-09-17 14:56:55 +02:00
Juergen Hoeller 4a51f6feef Polishing 2018-09-14 14:37:06 +02:00
Juergen Hoeller 4e9046ab6e Correct linkplain javadoc in BufferingClientHttpRequestFactory
Issue: SPR-17261

(cherry picked from commit e47355078c)
2018-09-11 15:16:59 +02:00
Juergen Hoeller e873004b52 Revise ServletUriComponentsBuilder javadoc
Issue: SPR-17255
2018-09-07 18:27:32 +02:00
Spring Buildmaster 5f465d056f Next Development Version 2018-09-07 14:10:07 +00:00
Juergen Hoeller 6a5d986b33 Fix SpEL compilation for non trivial elvis operand
Issue: SPR-17214
2018-09-07 13:19:47 +02:00
Juergen Hoeller 8ce9236b0f Polishing
(cherry picked from commit 95a56cd28d)
2018-08-31 13:22:55 +02:00
Juergen Hoeller 1a626ab948 SpelExpression consistently exposes EvaluationContext to compiled AST
Operator includes explicit support for Boolean comparisons now.

Issue: SPR-17229

(cherry picked from commit 51cee658d5)
2018-08-31 13:22:14 +02:00
Juergen Hoeller 56194a1051 Transactional timeout documented as seconds in annotation javadoc
Issue: SPR-17226

(cherry picked from commit 8c6f3505c4)
2018-08-31 13:21:37 +02:00
Juergen Hoeller a496836e46 Upgrade to Tomcat 8.5.33 and Netty 4.1.29 2018-08-24 13:28:55 +02:00
Juergen Hoeller 974e7b88ee Polishing 2018-08-24 13:28:29 +02:00
Juergen Hoeller 069704f4a0 Support Jackson filters in combination with serialization view
Issue: SPR-17209

(cherry picked from commit 03f1920106)
2018-08-24 13:28:23 +02:00
Juergen Hoeller d38eb9d6a0 SimpleAliasRegistry.hasAlias properly resolves multiple chained aliases
Issue: SPR-17191

(cherry picked from commit 2ac23badee)
2018-08-17 10:04:48 +02:00
Juergen Hoeller 5bd4f88af1 Polishing 2018-08-16 12:38:07 +02:00
Juergen Hoeller b16a3229bc Polishing 2018-08-15 18:10:25 +02:00
Rossen Stoyanchev a409233e80 Consistent logging of resolved exceptions
Issue: SPR-17178
2018-08-15 11:20:32 +03:00
Juergen Hoeller 7a97ba54ea Polishing 2018-08-14 22:03:05 +02:00
Juergen Hoeller 9de85f1336 MappingJackson2JsonView does not refer to "renderedAttributes" anymore
Issue: SPR-17182
2018-08-14 22:02:31 +02:00
Juergen Hoeller 484a2f3f2d Polishing 2018-08-13 14:23:41 +02:00
Juergen Hoeller 5bd5df3ec4 Post-processors consistently ignore ScopedObject/AopInfrastructureBean
Issue: SPR-17166
2018-08-12 20:40:26 +02:00
Juergen Hoeller b51685bf00 Post-processors consistently ignore ScopedObject/AopInfrastructureBean
Issue: SPR-17166
2018-08-11 22:58:36 +02:00
Juergen Hoeller 687d350b57 Polishing 2018-08-10 18:16:14 +02:00
Juergen Hoeller 73dfa9a968 Polishing 2018-08-09 19:01:14 +02:00
Juergen Hoeller 5a66a339a6 Polishing (typo fixes etc, aligned with 5.0.x) 2018-08-09 13:04:57 +02:00
Juergen Hoeller 45598ca53a Polishing 2018-08-09 02:56:56 +02:00
Juergen Hoeller 4b30fe2b44 Polishing 2018-08-09 02:34:12 +02:00
Juergen Hoeller e94c69149e AbstractAspectJAdvisorFactory uses AnnotationUtils.getValue 2018-08-09 01:52:16 +02:00
Juergen Hoeller c69fdfadfc Polishing 2018-08-09 01:17:10 +02:00
Juergen Hoeller bd060a19ac Expose checkbox field marker as 'hidden' to RequestDataValueProcessor
Issue: SPR-17147

(cherry picked from commit fa72186e28)
2018-08-09 01:17:05 +02:00
Juergen Hoeller 5515112f87 Polishing 2018-08-07 21:23:43 +02:00
Juergen Hoeller 89cadfa8d9 Polishing 2018-08-07 02:38:54 +02:00
Juergen Hoeller 73da153e5c DisposableBean javadoc refers to singletons as well as scoped beans
Issue: SPR-17131

(cherry picked from commit f155d21c95)
2018-08-07 02:37:02 +02:00
Juergen Hoeller 75b323e6c2 Polishing 2018-08-02 17:39:39 +02:00
Juergen Hoeller 13637ec3b5 Polishing
(cherry picked from commit dc36bb34c7)
2018-08-02 15:12:54 +02:00
Juergen Hoeller 7da02fb7e3 SchedulerAccessor catches cluster race conditions on job rescheduling
Issue: SPR-17114

(cherry picked from commit fa97aab8be)
2018-08-02 15:12:41 +02:00
Juergen Hoeller 92c210201e Polishing 2018-08-01 12:32:09 +02:00
Juergen Hoeller ae6d778c3e Polishing 2018-07-31 22:25:44 +02:00
Juergen Hoeller e24ac55480 Polishing 2018-07-30 23:05:57 +02:00
Juergen Hoeller b17a6f9e03 Polishing 2018-07-27 18:41:12 +02:00
Juergen Hoeller 4c050207e7 Polishing 2018-07-26 23:37:48 +02:00
Juergen Hoeller 7ac99c1c2d Revise BeanFactory vs ApplicationContext section in reference docs
Issue: SPR-17095
2018-07-26 19:02:12 +02:00
Juergen Hoeller 42e550a178 Polishing 2018-07-26 16:00:38 +02:00
Juergen Hoeller 1b78afe445 Properly identify event-related ClassCastExceptions on JDK 11
Issue: SPR-17093

(cherry picked from commit e458777925)
2018-07-26 15:15:47 +02:00
Juergen Hoeller 001cecd46a MethodBeforeAdviceInterceptor implements BeforeAdvice marker interface
Includes related polishing in the advice interceptor implementations.

Issue: SPR-17088

(cherry picked from commit 4e03d3fdcb)
2018-07-25 20:32:34 +02:00
Juergen Hoeller 21b7dc1ce4 Backport of WebMvcConfigurationSupport javadoc revision
Includes related polishing.
2018-07-25 15:54:02 +02:00
Juergen Hoeller a403a754e9 BeanFactoryAdvisorRetrievalHelper avoids synchronization for name cache
Issue: SPR-16570
2018-07-24 16:43:25 +02:00
Juergen Hoeller 2ae2249842 Polishing 2018-07-24 15:17:33 +02:00
Juergen Hoeller 484addb4f8 Polishing 2018-07-20 17:04:17 +02:00
Juergen Hoeller 65e423219e Polishing 2018-07-20 00:41:35 +02:00
Juergen Hoeller 22fc3255b7 Polishing 2018-07-19 13:47:03 +02:00
Juergen Hoeller 322b0f431f Javadoc update: ConfigurationClassPostProcessor is priority-ordered
Issue: SPR-17062

(cherry picked from commit c66f9d8)
2018-07-19 13:46:40 +02:00
Juergen Hoeller 1ff1c950fb Consistent exposure of nested parameter type in binding exceptions
(cherry picked from commit ed54895)
2018-07-18 20:11:30 +02:00
Juergen Hoeller 1e9b2b1c07 Update ref doc references to Number/Currency/PercentStyleFormatter
Issue: SPR-17022
2018-07-18 14:43:23 +02:00
Juergen Hoeller 19e944bd4f UrlBasedViewResolver exposes redirect prefix as bean name
Issue: SPR-17045
2018-07-18 14:43:14 +02:00
Stephane Nicoll e9e864b093 Fix typo
Issue: SPR-17042
2018-07-15 16:19:46 +02:00
Juergen Hoeller f4b644dfec Polishing 2018-07-06 15:28:15 +02:00
Juergen Hoeller b129fb4b62 Upgrade to Jackson 2.8.11.2 and SLF4J 1.7.25 2018-07-06 02:10:53 +02:00
Juergen Hoeller 50f7ffddf8 Polishing 2018-07-04 23:07:08 +02:00
Juergen Hoeller 4298744c4a Polishing 2018-07-03 17:06:35 +02:00
Juergen Hoeller 44b2657c8e ConcurrentReferenceHashMap caches EntrySet in volatile field
Includes an efficient implementation of isEmpty(), not relying on a full entry count but rather backing out once a non-empty hash segment has been found.

Issue: SPR-16994
2018-07-03 17:05:38 +02:00
Juergen Hoeller 9f69638420 Same method filtering in ConstructorResolver and getTypeForFactoryMethod
Issue: SPR-16999

(cherry picked from commit 0052c89)
2018-07-03 17:05:18 +02:00
Juergen Hoeller 740751bc01 Polishing 2018-06-29 23:05:40 +02:00
Juergen Hoeller de8d4e917d Upgrade to Tomcat 8.5.32 2018-06-29 21:21:31 +02:00
Juergen Hoeller fa8acfafbf Polishing 2018-06-29 21:21:19 +02:00
Juergen Hoeller d5bfddac69 Up-to-date coverage of task executor and scheduler variants
Includes a clarification of ThreadPoolExecutor configuration options and a note on early AsyncConfigurer initialization.

Issue: SPR-16944
Issue: SPR-16945

(cherry picked from commit d58c09b)

(cherry picked from commit 5a11112)
2018-06-29 21:21:11 +02:00
Juergen Hoeller 1b0d838a19 Support for new JsonMappingException wording in Jackson 2.9
Issue: SPR-16947

(cherry picked from commit 6d0f8bf)
2018-06-29 21:20:52 +02:00
Spring Buildmaster a0f52bf633 Next Development Version 2018-06-12 14:49:55 +00:00
Juergen Hoeller a9dd927870 Remove outdated HandlerAdapter references from annotation javadoc
Includes removal of PathVariable's MultiValueMap support claim.

Issue: SPR-16936
2018-06-12 11:48:45 +02:00
Brian Clozel 323ccf99e5 Restrict HTTP methods on Servlet HiddenHttpMethodFilter
This commit restricts the allowed HTTP methods on HiddenHttpMethodFilter
(Servlet variant) to the following: PUT, DELETE, PATCH.

This filter is meant to be used to simulate those methods from HTML
forms sent by browsers, so no other methods are allowed.

Issue: SPR-16836
(Cherry-picked from f64fa3dea1)
2018-06-11 19:18:28 +02:00
Juergen Hoeller 437eca0b25 Upgrade to Netty 4.1.25 2018-06-11 17:04:18 +02:00
Juergen Hoeller 965f3c6434 Polishing 2018-06-11 17:00:51 +02:00
Juergen Hoeller 6df7ba2447 Remove outdated javadoc references to SpEL lambda functions
Issue: SPR-16930
2018-06-11 16:55:52 +02:00
Juergen Hoeller 1d6f71718d AbstractMethodMessageHandler processes Error as MessageHandlingException
Issue: SPR-16912
2018-06-11 16:49:43 +02:00
Juergen Hoeller 4a6e9a5557 ReflectivePropertyAccessor caches sorted methods per class
Issue: SPR-16882
2018-06-11 16:47:52 +02:00
Juergen Hoeller 357ca21675 Correct code example for YamlProcessor.setDocumentMatchers
Issue: SPR-16849

(cherry picked from commit 455d8ac)
2018-06-11 16:46:45 +02:00
Sebastien Deleuze 874859493b Deprecate JSONP and disable it by default in Jackson view
Issue: SPR-16798
2018-06-08 12:33:27 +02:00
Sam Brannen 75a6f3b2b6 Document JUnit Jupiter options in Spring 4.3.x
Issue: SPR-16446
2018-06-04 15:05:27 +02:00
Stephane Nicoll 88456d4799 Fix faulty BeanPostProcessorChecker logs with @EnableCaching
Issue: SPR-16896
2018-06-04 15:03:04 +02:00
Rossen Stoyanchev c44de3c5df Minor update to STOMP chapter
Issue: SPR-16861
2018-05-23 21:57:53 -04:00
Juergen Hoeller 9d1789e718 Revised code examples for stored procedure type declarations
Issue: SPR-16811
2018-05-16 09:46:39 +02:00
Juergen Hoeller 849b6ccb8b SchedulerFactoryBean triggers shutdown after registration failure
Issue: SPR-16816
2018-05-16 09:46:31 +02:00
Juergen Hoeller 997ca5cd3f Query termination for JPA 2.1 StoredProcedureQuery.execute() method
Includes backported support for JPA 2.2 getResultStream() method.

Issue: SPR-16826
2018-05-16 09:46:11 +02:00
Spring Buildmaster a54bc6650e Next Development Version 2018-05-08 07:48:37 +00:00
Juergen Hoeller 70424a7e3d Polishing 2018-05-08 00:12:18 +02:00
Juergen Hoeller 318d04cd2b Explicit coverage of root vs cause exception matching in MVC ref docs
Issue: SPR-16743

(cherry picked from commit a200df6)
2018-05-08 00:02:56 +02:00
Juergen Hoeller d9ff109b0f Polishing
(cherry picked from commit b4f83db)
2018-05-07 15:01:22 +02:00
Juergen Hoeller 8501cef98d Upgrade to Tomcat 8.5.31 2018-05-05 16:37:20 +02:00
Juergen Hoeller c99a104919 Polishing 2018-05-05 16:36:52 +02:00
Juergen Hoeller 193c289080 ResponseEntityExceptionHandler rethrows unknown exception (for further processing in DispatcherServlet's HandlerExceptionResolver chain)
Issue: SPR-16743

(cherry picked from commit 7b894fe)
2018-05-05 16:32:08 +02:00
Juergen Hoeller 9c3270ad35 Upgrade to Netty 4.1.24 2018-05-02 17:21:35 +02:00
Juergen Hoeller e4a9ade991 Consistent SpelEvaluationException messages in findAccessorForMethod
Issue: SPR-16762

(cherry picked from commit 30363c8)
2018-05-02 17:21:07 +02:00
Juergen Hoeller fbd83015b1 Expose FactoryBean's raw object on retrieval during post-processing
Issue: SPR-16783

(cherry picked from commit 9281f82)
2018-05-02 17:20:31 +02:00
Juergen Hoeller 3a15595d0c Introspect originating bean definition as configuration class candidate
Issue: SPR-16756

(cherry picked from commit c8b6233)
2018-05-02 17:15:36 +02:00
Juergen Hoeller 289a6091f1 SimpleClientHttpResponse catches any Exception on close
Issue: SPR-16773

(cherry picked from commit 21fad8e)
2018-05-02 17:15:14 +02:00
Rossen Stoyanchev 3502f6fdc2 Validate contextPath in RedirectView
Issue: SPR-16752
2018-04-23 15:27:22 -04:00
Juergen Hoeller 8d67a982ec Correctly delegate to OrderUtils.getPriority for DecoratingProxy
Issue: SPR-16739
2018-04-17 23:45:24 +02:00
Juergen Hoeller c09e10405b Workaround for generic parameter types on inner class constructors
Issue: SPR-16734
2018-04-17 15:59:08 +02:00
Juergen Hoeller 6a727e1ed7 OperatorMatches flags misguided evaluation attempts as FLAWED_PATTERN
Issue: SPR-16731

(cherry picked from commit d4a55a2)
2018-04-17 13:46:37 +02:00
Rossen Stoyanchev 246a6db1ca Selector header name is exposed for configuration
Issue: SPR-16732
2018-04-17 00:20:12 -04:00
Sam Brannen 8748ba4c4b Suppress warning in SpringFailOnTimeoutTests 2018-04-14 16:46:57 +02:00
Juergen Hoeller 2989f01013 Cache-safety check for sibling loaders resolving the same classes
Issue: SPR-16714
2018-04-12 21:38:57 +02:00
Juergen Hoeller c6a7732a30 Consistent getTypeForFactoryMethod result for parameterized method
Issue: SPR-16720

(cherry picked from commit 6184c4e)
2018-04-12 21:38:12 +02:00
Juergen Hoeller e54c9d4a93 Fine-tuned JCA MessageEndpoint exception logging and propagation
Issue: SPR-16717

(cherry picked from commit 8e1ecec)
2018-04-12 21:37:45 +02:00
Juergen Hoeller ac19c696fe Revised reference example for linkable controller method signature
Issue: SPR-16710

(cherry picked from commit 7ee6130)
2018-04-12 21:37:39 +02:00
Sam Brannen fecbcd4e93 Expand scope of SpringFailOnTimeoutTests
Issue: SPR-16716
2018-04-12 10:58:21 +02:00
Igor Suhorukov 59396e1a6f Throw exception from user code in SpringFailOnTimeout even if a timeout occurs
Issue: SPR-16717
2018-04-12 10:58:21 +02:00
Juergen Hoeller c4ef47b29f Upgrade to Tomcat 8.5.30 and Netty 4.1.23 2018-04-11 16:51:10 +02:00
Juergen Hoeller c2fdd56107 Polishing 2018-04-11 16:50:48 +02:00
Juergen Hoeller 98536e1387 Proper exception for controller method return types that do not work with MvcUriComponentsBuilder (e.g. final classes)
Issue: SPR-16710
2018-04-11 16:50:38 +02:00
Spring Buildmaster ba13950d3a Next Development Version 2018-04-09 14:57:59 +00:00
Rossen Stoyanchev 0009806deb Re-use EvaluationContext in DefaultSubscriptionRegistry
Rather than create a new EvaluationContext instance per evaluation, we
now create a statically shared instance, without the root object in it,
and re-use it for all evalutations.
2018-04-09 10:05:50 -04:00
Rossen Stoyanchev 6deee3e818 TestDispatcherServlet unwraps to find mock request
Issue: SPR-16695
2018-04-06 11:21:25 -04:00
Andy Clement d3acf45ea4 Modify SpEL code gen to take account of null safe refs
With this change the code generation for method and property
references is modified to include branching logic in the
case of null safe dereferencing (?.). This is complicated
by the possible usage of primitives on the left hand side
of the dereference. To cope with this case primitives are
promoted to boxed types when this situation occurs enabling
null to be passed as a possible result.

Issue: SPR-16489
2018-04-05 14:36:36 -07:00
Spring Buildmaster 573f1d77f2 Next Development Version 2018-04-03 20:10:45 +00:00
Juergen Hoeller 1ca06537c1 Polishing 2018-04-03 13:20:09 +02:00
Juergen Hoeller 1ab0850303 Revised mime.types file with cpp extension and updated modification docs
Issue: SPR-16678

(cherry picked from commit 9601d4b)
2018-04-03 13:19:34 +02:00
Juergen Hoeller 2a9eaab674 Remove outdated declarations from spring-aspects build 2018-03-31 23:32:20 +02:00
Juergen Hoeller 1fbd38c2d8 Upgrade to Groovy 2.4.15 2018-03-31 19:54:41 +02:00
Juergen Hoeller 49eafe4261 Polishing 2018-03-31 19:54:12 +02:00
Juergen Hoeller b0ed385f84 Polishing 2018-03-31 17:06:33 +02:00
Juergen Hoeller 5d54adfb9a Selective backport of annotation retrieval refinements (from 5.0.5)
In particular AnnotationTypeFilter's ignoring of standard Java interfaces, AnnotationUtils.clearCache() and a few extra common classes in ClassUtils.

Issue: SPR-16667
Issue: SPR-16675
2018-03-31 17:03:59 +02:00
Juergen Hoeller 1cbc353dd1 Consistent Ordered.LOWEST_PRECEDENCE declarations for default order
(cherry picked from commit 6393e5c)
2018-03-31 17:02:41 +02:00
Juergen Hoeller 4cf1795359 Consistent to/cc/bcc array handling and revised hashCode without text
Issue: SPR-16671

(cherry picked from commit 1cc513d)
2018-03-31 17:02:12 +02:00
Juergen Hoeller 5629fa2c9f Pass type name into PreparedStatement.setNull in case of Types.OTHER
Issue: SPR-16669

(cherry picked from commit 9a722b4)
2018-03-31 17:01:47 +02:00
Sam Brannen 2903cb7f50 Polishing 2018-03-30 11:35:07 +02:00
Rossen Stoyanchev 986d219391 Replaces rather than prepend contextPath
Issue: SPR-16650
2018-03-29 18:26:31 -04:00
Rossen Stoyanchev de4da5ea4e Improve docs on forwarded headers
Issue: SPR-16660
2018-03-29 16:26:58 -04:00
Rossen Stoyanchev e8c656d2bc Reject invalid forwarded headers
Issue: SPR-16660
2018-03-29 16:16:20 -04:00
Juergen Hoeller bcda243f63 Polishing 2018-03-29 17:34:28 +02:00
Juergen Hoeller 64f304c333 Consistent references to primitive types (in alphabetical order)
(cherry picked from commit 08dad4e)
2018-03-29 17:33:13 +02:00
Juergen Hoeller 5f6b04251e Workaround for inner class constructor parameter annotation bug in javac
Issue: SPR-16652

(cherry picked from commit 53d0139)
2018-03-29 17:30:07 +02:00
Juergen Hoeller 618cb6155c Correct description for doWithLocalFields
Issue: SPR-16658

(cherry picked from commit 3ac46da)
2018-03-29 17:29:58 +02:00
nkjackzhang f3dd22da5b NamedParameterUtils.parseSqlStatement should parse :{x} style parameter correctly
In my opinion, we should parse ":{x}" style parameter as "x" is parameter using "NamedParameterUtils.parseSqlStatement",
so the condition "j - i > 2" is the correct condition, not "j - i > 3", because if "i" is the index of
":" in ":{x}", and "j" is the index of "}" in ":{x}",  "j - i == 3" is true.
Also add a test case for SPR-16663.

(cherry picked from commit 82cb5db)
2018-03-29 17:21:00 +02:00
Rossen Stoyanchev 6e4bbac6f7 MvcResult returns asyncResult after asyncDispatch
Issue: SPR-16648
2018-03-28 22:27:30 -04:00
Rossen Stoyanchev 2e4963fca3 Revert "Always specify charset for form data requests"
This reverts commit 1897d8e858.

Issue: SPR-16613
2018-03-28 11:58:24 -04:00
Juergen Hoeller 4d0adc7d95 Upgrade to Tomcat 8.5.29 2018-03-28 11:48:58 +02:00
Juergen Hoeller 3b3f27d5ff DefaultResponseErrorHandler.hasError avoids exception for unknown status
Issue: SPR-16604
2018-03-28 11:42:43 +02:00
Juergen Hoeller f32b13c5b3 Restored original 4.3.x expectation for property access on null target 2018-03-28 11:40:24 +02:00
Rossen Stoyanchev 1897d8e858 Always specify charset for form data requests
Issue: SPR-16613
2018-03-27 20:04:53 -04:00
Rossen Stoyanchev 71126faae0 MimeTypeUtils trims parameter names / values
Issue: SPR-16630
2018-03-27 20:04:53 -04:00
Juergen Hoeller 9cc03fa8b0 Polishing 2018-03-28 02:03:31 +02:00
Juergen Hoeller 59189e5957 Backported core container concurrency refinements
Issue: SPR-16620
Issue: SPR-16625
Issue: SPR-16627
2018-03-28 01:23:50 +02:00
Juergen Hoeller 65a8aa1c09 Backported DataBindingPropertyAccessor and DataBindingMethodResolver
Issue: SPR-16588
2018-03-28 01:22:59 +02:00
Juergen Hoeller f046a066ec Simplified separator check within isInvalidEncodedPath
Issue: SPR-16616
2018-03-28 01:22:01 +02:00
Juergen Hoeller 6e1cac9145 AcceptHeaderLocaleResolver keeps language match among supported locales
Issue: SPR-16599
2018-03-28 01:21:36 +02:00
Juergen Hoeller 7cafa6764c Validate declared annotations before deciding between reflection and ASM
Issue: SPR-16564
2018-03-28 01:20:59 +02:00
Juergen Hoeller c1cb0311aa Avoid triggering lazy resolution in MultipartResolver.cleanupMultipart
Issue: SPR-16640

(cherry picked from commit 10cb2cc)
2018-03-28 01:19:22 +02:00
Juergen Hoeller f2478cf8cf Contextual BeanCreationException in case of depending on a missing bean
Issue: SPR-16628

(cherry picked from commit 937cd48)
2018-03-28 01:19:12 +02:00
Juergen Hoeller 977084a6b8 Correct documentation of default HttpMessageConverters in RestTemplate
Issue: SPR-7885

(cherry picked from commit 442ddb0)
2018-03-28 01:18:42 +02:00
Juergen Hoeller 0e7e49bab0 Deprecate TableMetaDataContext.getSimulationQueryForGetGeneratedKey
(cherry picked from commit 2c7efbb)
2018-03-28 01:18:28 +02:00
Juergen Hoeller 301ba01427 CallMetaDataContext handles 'procedureColumnResult' as return parameter
Issue: SPR-16611

(cherry picked from commit b7c4238)
2018-03-28 01:18:20 +02:00
Juergen Hoeller 881817678f Scope annotation in class hierarchies vs XML bean definition inheritance
Issue: SPR-16602

(cherry picked from commit 914b247)
2018-03-28 01:18:05 +02:00
Juergen Hoeller b8c92ce931 Consistent volatile access to running flag in Lifecycle implementations
Issue: SPR-16596
Issue: SPR-16488

(cherry picked from commit d4a8f76)
2018-03-28 01:17:53 +02:00
Juergen Hoeller 6158634d67 Clarified repeatable PropertySource annotation vs use as meta-annotation
Issue: SPR-16592

(cherry picked from commit c4e9ce8)
2018-03-28 01:17:18 +02:00
Juergen Hoeller 8d8bb04783 ConcurrentReferenceHashMap properly handles getOrDefault for null values
Issue: SPR-16584

(cherry picked from commit 356ef45)
2018-03-28 01:17:09 +02:00
Juergen Hoeller 2cac3a8255 InterceptingClientHttpRequest adapts to StreamingHttpOutputMessage
Issue: SPR-16582

(cherry picked from commit 4173022)
2018-03-28 01:16:59 +02:00
Juergen Hoeller 25a3019234 URIEditor uses straight ClassPathResource.getURI() access
Issue: SPR-16581

(cherry picked from commit 499128d)
2018-03-28 01:16:50 +02:00
Juergen Hoeller 3dff1b3f6e SimpleAliasRegistry fully synchronizes registerAlias and removeAlias
Issue: SPR-16577

(cherry picked from commit 1b1a69a)
2018-03-28 01:16:35 +02:00
Juergen Hoeller b1295d0499 TransactionTemplate equality for same transaction manager only
Issue: SPR-16572

(cherry picked from commit df80614)
2018-03-28 01:16:24 +02:00
Juergen Hoeller eeeb0a6546 Consistent result synchronization in WebAsyncManager
Issue: SPR-16571

(cherry picked from commit cf74b1b)
2018-03-28 01:16:13 +02:00
Juergen Hoeller 1bde920cce Quick access to volatile field (full synchronization only for lazy init)
Issue: SPR-16570

(cherry picked from commit 50253f6)
2018-03-28 01:16:06 +02:00
Rossen Stoyanchev e02ff3a0da MimeTypeUtils uses SecureRandom
The prevailing current wisdom is to use the default constructor for
secure and let it pick the best algorithm for the OS.

On Java 8 (Oracle), Linux this results in "NativePRNG" which uses
/dev/random (potentially blocking) for the initial seed, and
/dev/urandom (non-blocking) for subsequent calls to nextInt.

Issue: SPR-16635
2018-03-23 21:52:30 -04:00
Rossen Stoyanchev ff377a3836 Minor typo in docs 2018-03-23 11:11:40 -04:00
Rossen Stoyanchev ddb2bdf8c6 Improve docs on @Controller methods in STOMP section
Issue: SPR-16631
2018-03-23 11:07:42 -04:00
Rossen Stoyanchev b9ebdaaf37 Backport clean duplicate separators in resource URLs
Issue: SPR-16616
2018-03-21 23:18:36 -04:00
Rossen Stoyanchev 4187e04b69 Backport doc change 2018-03-21 22:47:13 -04:00
Rossen Stoyanchev d512cca3fd Reactor2TcpClient constructor with address supplier
Issue: SPR-12452
2018-03-20 11:41:54 -04:00
Rossen Stoyanchev 4bc3e0c2b4 Add SimpleEvaluationContext
Issue: SPR-16588
2018-03-14 16:10:28 -04:00
Sam Brannen d57d914b26 Make method params final for use in anonymous inner class
Issue: SPR-16587
2018-03-13 17:10:54 +01:00
Sam Brannen 68463e2018 Support target type in JsonPath assertions for MockMvc results
This commit picks up where SPR-14498 left off by adding support for an
explicit target type when using JsonPath to perform an assertion against
the response content using a Hamcrest Matcher.

Specifically, there is a new overloaded value(Matcher<T>, Class<T>)
method in JsonPathResultMatchers for use with Hamcrest matchers where
the target type (i.e., Class<T>) can be specified.

Issue: SPR-16587
2018-03-13 16:06:39 +01:00
Brian Clozel 6fa9539ae2 Don't implicitly check preconditions on PUT requests
Prior to this commit, the `HttpEntityMethodProcessor` would check HTTP
conditions on non-safe requests (i.e. not GET/HEAD). This would prevent
Controllers from returning `ResponseEntity` containing response headers
with updated values of `"Last-Modified"` or `ETag` once the resource has
been updated.

This commit avoids those checks for non GET/HEAD requests - this code
can still be leveraged from Controllers themselves using
`ServletWebRequest::checkNotModified` methods.

Issue: SPR-15780
(cherry picked from ed7684d2b2)
2018-03-08 20:10:25 +01:00
Yannik Hampe ff53a26333 Make MockRestRequestMatchers independent of JUnit (#1720)
MockRestRequestMatchers was using org.junit.Assert.assertNotNull
and thus could not be used in projects that use e.g. TestNG instead
of JUnit 4.
2018-03-08 13:37:26 +01:00
Juergen Hoeller b70d400c71 Strong recommendation for OpenPDF 1.0.5 instead of iText 2.1.7
Issue: SPR-16107
2018-03-07 16:54:04 +01:00
Juergen Hoeller 346d0e271d Polishing 2018-03-07 16:24:40 +01:00
Juergen Hoeller c15f23bf0c Reliably expose nested cause exception message for PersistenceException
Issue: SPR-16559

(cherry picked from commit eb9c43d)
2018-03-07 16:23:12 +01:00
Juergen Hoeller 0962c66592 Consistent incrementer arrangement for PostgreSQL, DB2 and SAP HANA
Includes related polishing in core.metadata and datasource.embedded and a revision of the corresponding database definitions in sql-error-codes.

Issue: SPR-16558

(cherry picked from commit 82515a3)
2018-03-07 16:22:52 +01:00
Juergen Hoeller b643f7836c Drop version check in isGetGeneratedKeysSimulated (for PostgreSQL 10)
Issue: SPR-16556

(cherry picked from commit 4a4f2c2)
2018-03-07 16:22:39 +01:00
Brian Clozel 56fdda167e Guard against invalid paths in ResourceUrlProvider
This commit makes sure that no `StringIndexOutOfBoundsException` is
thrown when `getForRequestUrl` is called with a URL that's shorter than
the expected context path.

Issue: SPR-16526
(cherry picked from commit 6d26e61ac7)
2018-03-05 15:28:36 +01:00
Juergen Hoeller 017f2a8ccc Upgrade to Animal Sniffer 1.16 2018-03-05 13:54:55 +01:00
Juergen Hoeller f7898951bd Correct description for class-level @Transactional with AspectJ
Includes isolation level clarifications.

Issue: SPR-16552
Issue: SPR-16463
2018-03-05 13:40:24 +01:00
Juergen Hoeller bd6b7b08f3 Concurrency and exception message refinements for test transactions
(cherry picked from commit a0cc800)
2018-03-05 13:40:13 +01:00
Juergen Hoeller bc043245cc Polishing 2018-03-03 17:18:44 +01:00
Juergen Hoeller 6e8a3fb4db Upgrade to Groovy 2.4.14 2018-03-03 17:18:32 +01:00
Juergen Hoeller 1f12214b45 Polishing 2018-03-02 13:11:31 +01:00
Juergen Hoeller c6bd0c9f3d Revert MessageConsumer interrupt calls (just log wait count on shutdown)
Issue: SPR-16536
2018-03-02 13:09:59 +01:00
Rossen Stoyanchev fb22915563 Correct log level
Issue: SPR-16528
2018-03-01 15:58:20 -05:00
Juergen Hoeller c5c27f2963 Polishing 2018-03-01 01:48:26 +01:00
Juergen Hoeller 3e6cfb7c6d WebApplicationContextFacesELResolver.isReadOnly returns true for WAC
Issue: SPR-16543

(cherry picked from commit 4781627)
2018-03-01 01:43:19 +01:00
Juergen Hoeller 8e68ac44d2 Polishing 2018-03-01 01:12:30 +01:00
Juergen Hoeller 81c50dc674 Polishing 2018-02-28 16:29:46 +01:00
Juergen Hoeller 57aa3d1e3b Consistent but local aspect instantiation in AspectJProxyFactory (4.3.x) 2018-02-28 15:49:48 +01:00
Juergen Hoeller 2c45b09263 Polishing 2018-02-28 15:08:09 +01:00
Juergen Hoeller 59f12635f9 Interrupt listener invoker threads on shutdown (after initial wait step)
Issue: SPR-16536

(cherry picked from commit 95aad9c)
2018-02-28 15:07:53 +01:00
Juergen Hoeller 901d48c803 Support for ResolvableType.getType().getTypeName() on Java 8
Issue: SPR-16535

(cherry picked from commit 6663d0f)
2018-02-26 17:31:12 +01:00
Juergen Hoeller 0bc7c47bea Polishing 2018-02-26 13:24:50 +01:00
Juergen Hoeller 06e2bada0a ConcurrentMapCache.get(key, valueLoader) avoids race condition
Issue: SPR-16533
2018-02-26 13:24:25 +01:00
Juergen Hoeller 8181c0237f Enforce GMT timezone for testBindInstantFromJavaUtilDate
Issue: SPR-16534

(cherry picked from commit 7d89de0)
2018-02-26 13:23:02 +01:00
Juergen Hoeller d4af8c86b2 Polishing 2018-02-25 21:44:34 +01:00
igor-suhorukov 39ddd0f349 Polish: String function use should be optimized for single characters
(cherry picked from commit 49fd724)
2018-02-25 21:44:00 +01:00
Juergen Hoeller 073e78b68d Polishing 2018-02-25 15:04:19 +01:00
Juergen Hoeller f9754f92f4 Mark Castor tests as deprecated
Issue: SPR-16219

(cherry picked from commit 85984f3)
2018-02-25 15:04:11 +01:00
igor-suhorukov d5f358c33c Polish: Array designators "[]" should be on the type, not the variable
(cherry picked from commit c782075)
2018-02-25 15:03:54 +01:00
Juergen Hoeller 295df21f06 Polishing 2018-02-25 00:48:00 +01:00
Juergen Hoeller 57a9e8e6dd Efficiently merge bean name result with parent result (possibly empty)
(cherry picked from commit 7f58d9ede0)
2018-02-25 00:41:51 +01:00
Juergen Hoeller e83491fbe9 GsonHttpMessageConverter keeps output stream open (for SseEmitter)
Issue: SPR-16529
2018-02-23 11:02:34 +01:00
Juergen Hoeller 37ee264fbf Local mergeStringArrays variant for Portlets (superseding StringUtils) 2018-02-22 15:48:35 +01:00
Juergen Hoeller 8b5563ecab Deprecated StringUtils.mergeStringArrays
(cherry picked from commit 0f74052)
2018-02-22 15:26:06 +01:00
Juergen Hoeller 0a3a82fd83 Upgrade to Netty 4.1.22 2018-02-22 14:30:01 +01:00
Juergen Hoeller 8b071633d3 Consistent use of ClassUtils.toClassArray (and related polishing) 2018-02-22 14:27:57 +01:00
Juergen Hoeller caed04473e Consistent HttpMethod identity comparisons
(cherry picked from commit 0de36d2)
2018-02-18 22:28:37 +01:00
Juergen Hoeller 87abdb92da Polishing 2018-02-16 21:02:00 +01:00
Juergen Hoeller 6d11b40353 Consistent use of StringUtils.toStringArray 2018-02-16 19:48:43 +01:00
Juergen Hoeller 350f318d2e FormTag skips rendering of hidden fields in case of empty Map
Issue: SPR-16498

(cherry picked from commit 6d75732)
2018-02-16 19:47:44 +01:00
Rossen Stoyanchev 608ef46516 ForwardedHeaderFilter handles query+fragment correctly
Issue: SPR-16506
2018-02-16 12:41:23 -05:00
Juergen Hoeller d60446a4fe Explicit documentation notes on transacted sessions vs AUTO_ACKNOWLEDGE
Issue: SPR-16487

(cherry picked from commit 95f7180)
2018-02-14 16:38:46 +01:00
Juergen Hoeller 722cb36e01 Consistent Class array vs vararg declarations (and related polishing)
(cherry picked from commit 3b810f3)
2018-02-14 16:38:28 +01:00
Juergen Hoeller 5ba37762fe Consistent ControllerAdvice applicability against user-declared class
Issue: SPR-16496

(cherry picked from commit 46cbdff)
2018-02-14 16:38:21 +01:00
Juergen Hoeller f2dc075335 Defensively handle DatabaseMetaData.getConnection() returning null
Issue: SPR-16495

(cherry picked from commit 766e602)
2018-02-14 16:37:55 +01:00
Juergen Hoeller 3b0eca921c Refined exception messages 2018-02-13 14:58:34 +01:00
Juergen Hoeller efe2539cf3 Upgrade to Tomcat 8.5.28 and Jackson 2.8.11.1 2018-02-13 14:21:11 +01:00
Juergen Hoeller 0030ff8711 Polishing 2018-02-13 14:20:07 +01:00
Juergen Hoeller f93ca28884 Avoid unused arguments for internal delegates
(cherry picked from commit b449928)
2018-02-13 14:17:59 +01:00
Juergen Hoeller 4be416e2ca SubProtocolWebSocketHandler closes sessions outside of lifecycle monitor
Issue: SPR-16488

(cherry picked from commit 3c631f8)
2018-02-13 14:17:52 +01:00
Rossen Stoyanchev 2033f50f22 Fix regression in MappingJackson2MessageConverter
As of 4.3.13 MappingJackson2MessageConverter uses the MethodParameter
hint to obtain generic type information but it needs to be careful, and
nest one level, if the target parameter type has a Message wrapper.

Issue: SPR-16486
2018-02-12 22:03:37 -05:00
Juergen Hoeller e33fb892f1 Upgrade to Netty 4.1.21 2018-02-12 13:50:06 +01:00
Juergen Hoeller afe461609c Polishing (selective backports from master) 2018-02-12 13:45:53 +01:00
Juergen Hoeller 33d655a634 Consistent handling of InterruptedException (plus setSchedulerFactory)
Issue: SPR-16479
Issue: SPR-16439

(cherry picked from commit 39201ad)
2018-02-12 13:44:54 +01:00
Juergen Hoeller 2654dbfcf1 Relaxed procedure existence check on Oracle (for non-exposed synonyms)
Issue: SPR-16478

(cherry picked from commit fc93f99)
2018-02-12 13:44:45 +01:00
Juergen Hoeller 14440949b3 Test with all-negated profile condition
Issue: SPR-16465

(cherry picked from commit 285b01f)
2018-02-12 13:44:24 +01:00
Juergen Hoeller 05dec6d23e Consistent use of @throws instead of @exception
(cherry picked from commit 5c813a3)
2018-02-12 13:44:17 +01:00
Juergen Hoeller cc77b4b995 Explicit notes on isolation level handling in participating transactions
Issue: SPR-16463

(cherry picked from commit 0ac117f)
2018-02-12 13:43:46 +01:00
Juergen Hoeller fd964ca4b1 Consistent object type exposure for JSON rendering (workaround for Gson)
Issue: SPR-16461

(cherry picked from commit 817a836)
2018-02-12 13:43:28 +01:00
Juergen Hoeller 5fd761ee39 MimeType.compareTo uses case-insensitive Charset (analogous to equals)
Issue: SPR-16458

(cherry picked from commit cfe7ff1)
2018-02-12 13:43:14 +01:00
Juergen Hoeller 8fda96cadb AcceptHeaderLocaleResolver falls back to language-only match among its supported locales
Issue: SPR-16457

(cherry picked from commit 4dc9645)
2018-02-12 13:42:33 +01:00
Juergen Hoeller 9926b68473 Avoid String concatenation for not-null assertion in BeanProperty/DirectFieldBindingResult
Issue: SPR-16455

(cherry picked from commit 9c069f6)
2018-02-12 13:41:50 +01:00
Juergen Hoeller d8a2672505 CachingConnectionFactory makes its Session caching inactive during reset
Issue: SPR-16450

(cherry picked from commit b6ecfcf)
2018-02-12 13:41:28 +01:00
Juergen Hoeller b125b5e398 Properly analyze Java 9 class cast messages for lambda event listeners
Issue: SPR-16435

(cherry picked from commit 89d2bd9)
2018-02-12 13:41:05 +01:00
Juergen Hoeller 65743a68e6 Deep BeanCurrentlyInCreationException check in getTypeForFactoryBean
Issue: SPR-16427

(cherry picked from commit 7772b91)
2018-02-12 13:40:38 +01:00
Juergen Hoeller f187ca6413 Notes about HibernateJpaVendorAdapter settings vs native Hibernate rules
Issue: SPR-16428

(cherry picked from commit e1fa65a)
2018-02-12 13:40:32 +01:00
Juergen Hoeller 13c213481a @EnableAspectJAutoProxy: per application context, requires aspectjweaver
Issue: SPR-14753
Issue: SPR-15801

(cherry picked from commit 0e734d8)
2018-02-12 13:40:19 +01:00
Juergen Hoeller ce9402618c Doc: no "useCodeAsDefaultMessage" for setValidationMessageSource
Issue: SPR-15986

(cherry picked from commit 37ab8a7)
2018-02-12 13:40:08 +01:00
Juergen Hoeller a041769799 AbstractClientSockJsSession.close propagates IOException from disconnect
Issue: SPR-16415

(cherry picked from commit cf100d4)
2018-02-12 13:39:30 +01:00
Juergen Hoeller 09cb7f4c31 Fine-tuned logging of WebSocket close exceptions
Issue: SPR-16409

(cherry picked from commit 8e2be91)
2018-02-12 13:39:23 +01:00
Juergen Hoeller 04f954956c ServletServerHttpRequest.getURI() ignores malformed query string
The resolved URI instance is also being cached now. This should not make a difference in a real Servlet environment but does affect tests which assumed they could modify an HttpServletRequest path behind a pre-created ServletServerHttpRequest instance. Our WebSocket test base class has been revised accordingly, re-creating the ServletServerHttpRequest in such a case.

Issue: SPR-16414

(cherry picked from commit 0e6f8df)
2018-02-12 13:39:11 +01:00
Rossen Stoyanchev fe4472dbeb MockHttpServletRequestBuilder decodes pathInfo
Previously MockHttpServletRequestBuilder calculated the pathInfo from the
provided URL without decoding the value. This meant that the pathInfo
incorrectly included URL encoded values.

Now MockHttpServletRequestBuilder properly decodes the pathInfo.

Backport of #0cd427bdd35e668dda6332ae2885d94c222d9c49.

Fixes: SPR-16453
2018-02-02 15:17:58 -05:00
Spring Buildmaster b708027e94 Next Development Version 2018-01-23 09:03:47 +00:00
Juergen Hoeller 333449598f Upgrade to Apache HttpClient 4.5.5 and Tomcat 8.5.27 2018-01-22 21:46:42 +01:00
Juergen Hoeller 03b2d9399e Polishing 2018-01-22 21:39:16 +01:00
Juergen Hoeller 4ccf33e36b Javadoc format and related polishing
(cherry picked from commit 9d0e62e)
2018-01-22 13:08:03 +01:00
Juergen Hoeller 5eebe946bd Upgrade to Netty 4.1.20 and Tomcat 8.5.24 2018-01-22 13:06:41 +01:00
Juergen Hoeller 13fa69bdaf Upgrade to ASM 6.0 level (for CGLIB 3.2.6)
Issue: SPR-16405

(cherry picked from commit 185c2bf)
2018-01-20 16:19:56 +01:00
Juergen Hoeller 4aeca67c4d Upgrade to CGLIB 3.2.6
Issue: SPR-16267
2018-01-20 14:46:46 +01:00
Rossen Stoyanchev b695b15243 Update STOMP docs on using dot as separator
Issue: SPR-16275
2018-01-19 22:35:56 -05:00
Rossen Stoyanchev ef4b62caa0 Refine "." separator support for STOMP messaging
After this commit DefaultUserDestinationResolves no longer looks at
whether AntPathMatcher is configured with "." as separator and rather
expects to be explicitly told whether to keep the leading slash in
translated destinations which actually depends on what the message
broker supports (e.g. RabbitMQ "/", Artemis ".") or how it is
configured (simple broker could be either way).

There is also a minor improvement in SimpMessagingTemplate to ensure
user destinations are correctly formed based on what the
DefaultUserDestinationResolver expects. When using "." as separtor it
allows sending messages to "queue.q1" rather than "/queue.q1".

Issue: SPR-16275
2018-01-19 22:35:49 -05:00
Rossen Stoyanchev 238e9ae59f Polish MessageBrokerConfigurationTests 2018-01-19 22:24:21 -05:00
Juergen Hoeller 347f2890df Upgrade to Jackson 2.8.11 2018-01-19 19:35:27 +01:00
Juergen Hoeller 8b5a013423 Polishing 2018-01-19 19:35:02 +01:00
Juergen Hoeller a73d9bbed5 Scheduled/JmsAnnotationBeanPostProcessor properly deals with nested proxies
Issue: SPR-16196
2018-01-19 19:13:38 +01:00
Juergen Hoeller c1bc74c83f ResponseEntityResponseExtractor tolerates unknown HTTP status codes
Issue: SPR-16371
2018-01-19 19:13:16 +01:00
Juergen Hoeller f68fdd4454 Proper null path checks in HierarchicalUriComponents
Issue: SPR-16364
2018-01-19 19:13:06 +01:00
Juergen Hoeller 19640ec3f9 Log non-loadable TestExecutionListener classes at debug level only
Issue: SPR-16369
2018-01-19 19:10:31 +01:00
Juergen Hoeller 69c882cfbc BridgeMethodResolver properly resolves all declared interfaces
Issue: SPR-16288
2018-01-19 19:08:17 +01:00
Juergen Hoeller 64af3a0f64 Use ArrayList instead of LinkedList for known size
Issue: SPR-16378
2018-01-19 19:07:10 +01:00
Juergen Hoeller d7959edb3e Improve performance of some string operations
Issue: SPR-16293
2018-01-19 19:05:07 +01:00
Juergen Hoeller 0b77c8835c Reduce access on user in SimpleBrokerMessageHandler.handleMessageInternal
Issue: SPR-16264
2018-01-19 19:04:57 +01:00
Timo Meinen 28f15057ac Log SQL parameters in EclipseLink when using showSql
As of EclipseLink 2.4.0 - Juno this is not sufficient to log
SQL parameter binding. Additionally,
eclipselink.logging.parameters must be enabled.

Issue: SPR-16383

(cherry picked from commit 823a16c)
2018-01-19 18:43:18 +01:00
Skelotron e5025419c2 Fix transaction timeout value overflow
Issue: SPR-16316

(cherry picked from commit b9e03cb)
2018-01-19 18:42:43 +01:00
Juergen Hoeller d53ede9bd3 CacheProxyFactoryBean exposes all relevant CacheInterceptor callbacks
Issue: SPR-16295

(cherry picked from commit b160f93)
2018-01-19 18:41:45 +01:00
Juergen Hoeller 092b3d4a52 Warning instead of error for non-present type filter class
Issue: SPR-16356

(cherry picked from commit 4adc820)
2018-01-19 18:41:18 +01:00
Juergen Hoeller bf4cadadda CachingConnectionFactory does not cache producer for temporary queue/topic
Issue: SPR-16353

(cherry picked from commit 72590db)
2018-01-19 18:41:06 +01:00
Juergen Hoeller a9bad580d9 FunctionReference's method field is volatile
Issue: SPR-16255

(cherry picked from commit 6a1fe0b)
2018-01-19 18:38:13 +01:00
Juergen Hoeller 6f6ff33202 Consider enum subclasses as simple value types as well
Issue: SPR-16278

(cherry picked from commit d3e0f4d)
2018-01-19 18:37:30 +01:00
Juergen Hoeller 4bb837582e Support for static field access on non-public enums
Issue: SPR-16284

(cherry picked from commit 9beb978)
2018-01-19 18:37:11 +01:00
Juergen Hoeller 3368dcae22 Avoid extra existence check in SimpleMetadataReaderFactory
Issue: SPR-16281

(cherry picked from commit 7ad69bf)
2018-01-19 18:37:00 +01:00
Rossen Stoyanchev 86704112b0 Update docs on stomp.js library
This is a backport of #357fb4.

Issue: SPR-15624
2018-01-18 14:51:40 -05:00
Rossen Stoyanchev d62dd2dd8d Polish MockRestServiceServer code
Cherry picked from #7ab4d0ca08
2018-01-17 13:04:32 -05:00
sdeleuze e935018b0c Fix SockJs CorsConfiguration for forbidden origins
After this commit, AbstractSockJsService uses the configured allowed
origins when generating the CorsConfiguration instead of "*".

As a consequence, forbidden origin requests still result in a 403
response but now with no CORS headers in order to improve consistency
between the status code and the headers.

Issue: SPR-16304
2018-01-15 18:17:08 +01:00
Stephane Nicoll 0747cd6a70 Make sure endpoint settings override default factory settings
Issue: SPR-16338
2018-01-15 15:45:55 +01:00
Rossen Stoyanchev 0a30b71dc3 Fix failing tests caused by previous commit 2018-01-12 12:36:24 -05:00
Rossen Stoyanchev 03118542f4 MockHttpInputMessage respects getBody contract
Issue: SPR-16367
2018-01-12 11:44:42 -05:00
sdeleuze 1b3b058ebd Refine forwarded protocol support
This commit refines forwarded protocol support in order to support
proxies that only set "X-Forwarded-Proto" header and not
"X-Forwarded-Port" by performing a reset of the port in such case.

"Forwarded" header support has been updated accordingly since it
also supports similar use case, as described in SPR-15504.

Issue: SPR-16262
2018-01-09 14:56:23 +01:00
Stephane Nicoll 8aa94aee27 Fix SpEL syntax
Issue: SPR-16315
2018-01-08 08:47:57 +01:00
Rossen Stoyanchev 6dbc828aa1 MappingJackson2MessageConverter uses generic type
This is a backport of the #583201 minus use of GenericTypeResolver
which in 5.0 has been refactored to provide a getJavaType method.

Issue: SPR-16252
2018-01-04 13:17:34 -05:00
nkjackzhang 3c31e0378f Polish Javadoc
Closes gh-1627
2017-12-23 14:20:49 +01:00
sdeleuze e6e6b8f4ad Allow interceptors to add existing header values
Additional commit to provide support of requests
that have a body.

Issue: SPR-15066
2017-12-13 09:47:55 +01:00
Rossen Stoyanchev 4fe94dffc0 Fix regression in StompHeaderAccessor
Issue: SPR-16265
2017-12-11 16:42:27 -05:00
sdeleuze 4b8a937bee Allow interceptors to add existing header values
Provide a fully mutable HttpHeaders to ClientHttpRequestInterceptors
of a RestTemplate when headers are set using HttpEntity. This avoids
UnsupportedOperationException if both HttpEntity and
ClientHttpRequestInterceptor add values for the same HTTP header.

Issue: SPR-15066
2017-12-11 17:56:48 +01:00
Spring Buildmaster 55fc731c59 Next Development Version 2017-11-27 10:39:19 +00:00
Juergen Hoeller 40a61277e1 Upgrade to Groovy 2.4.13 2017-11-26 17:57:04 +01:00
Juergen Hoeller 8c499cb10b Polishing 2017-11-26 17:56:35 +01:00
Juergen Hoeller 723b2b19a6 Consistent checks in DataAccessUtils (plus nullability hints in javadoc)
Issue: SPR-16225
2017-11-26 17:55:03 +01:00
Juergen Hoeller f09e252417 Polishing 2017-11-21 15:25:33 +01:00
Juergen Hoeller f3b8d7138c Consistent use of tabs for sample code in the reference documentation 2017-11-21 15:25:26 +01:00
Juergen Hoeller 47383fce97 Unit tests for configuration superclass inclusion
Issue: SPR-16217

(cherry picked from commit 08c95fb)
2017-11-21 15:25:17 +01:00
Juergen Hoeller 8206f0652b Deprecate Castor support
Issue: SPR-16219

(cherry picked from commit 08c7855)
2017-11-21 15:25:09 +01:00
jianglei 1b58fad228 Fix copy/paste in Javadoc
Closes gh-1601
2017-11-21 06:59:12 +01:00
Juergen Hoeller a58ef88f1d SqlParameterSourceUtils.createBatch polishing (partial backport)
Issue: SPR-16215
2017-11-20 13:33:50 +01:00
Juergen Hoeller 1d060ecff0 Document common use cases for @Order vs @Priority vs @DependsOn
Issue: SPR-16213

(cherry picked from commit 84699c8)
2017-11-20 13:33:23 +01:00
Juergen Hoeller 122a3fe9fd ResourceHttpRequestHandler uses EmbeddedValueResolverAware
(cherry picked from commit 20fcefc)
2017-11-20 13:32:50 +01:00
Rossen Stoyanchev 2a309a031a Revise charset by location support for static resources 2017-11-17 12:55:11 -05:00
Juergen Hoeller 03fef655ff Restored support for placeholders in mvc namespace resource locations
With the recent charset mechanism in place, we cannot rely on implicit placeholder parsing during String-to-Resource conversion anymore.

(cherry picked from commit 7af9910)
2017-11-16 10:03:14 +01:00
Juergen Hoeller a9e2040831 HibernateJpaVendorAdapter properly checks connectionReleaseOnClose
Issue: SPR-16162
2017-11-14 17:17:24 +01:00
Juergen Hoeller ffbaa26b4f End of first-class JDK 6 support
Issue: SPR-16185
2017-11-14 12:32:06 +01:00
Juergen Hoeller 586912792a Upgrade to Netty 4.1.17 and Undertow 1.3.33 2017-11-14 12:31:19 +01:00
Juergen Hoeller 640c8ff693 Polishing 2017-11-14 12:31:01 +01:00
Juergen Hoeller d52d9fd268 HibernateJpaVendorAdapter preserves connection release mode for JTA
Issue: SPR-16162
2017-11-14 12:30:49 +01:00
Juergen Hoeller f861f182fa Reduce access on headers for STOMP messaging
Issue: SPR-16165
2017-11-14 12:30:24 +01:00
Juergen Hoeller d5f34ed641 Correctly handle NVARCHAR, LONGNVARCHAR and NCLOBs
Issue: SPR-16154
2017-11-14 12:30:13 +01:00
Juergen Hoeller a88c47a120 Properly handle follow-up request after failure
Issue: SPR-16132
2017-11-14 12:30:04 +01:00
Juergen Hoeller 6dc73469f9 MethodReference treats proxy-targeting expressions as non-compilable
Issue: SPR-16191

(cherry picked from commit c30145d)
2017-11-14 12:28:15 +01:00
Juergen Hoeller 59d654b0cf Unit tests for unresolvable generics with partial mismatch
Issue: SPR-16179

(cherry picked from commit e2bb06e)
2017-11-14 12:27:51 +01:00
Juergen Hoeller 9779b8b2ab SpringValidatorAdapter skips value retrieval for Set field without index
Issue: SPR-16177

(cherry picked from commit 3091fee)
2017-11-14 12:27:42 +01:00
Juergen Hoeller 2c8a6bb6f5 Explicitly document UriTemplate as thread-safe
Issue: SPR-16173

(cherry picked from commit de78202)
2017-11-14 12:27:31 +01:00
Juergen Hoeller 5800c7a18a Comprehensive documentation on injection point matching
Issue: SPR-16142

(cherry picked from commit a5da05c)
2017-11-14 12:27:21 +01:00
Juergen Hoeller dc0a934c99 MockHttpServletResponse.getDateHeader returns -1 for non-existent header
Includes consistent getDateHeader results in both MockHttpServletResponse variants (spring-test and spring-web)

Issue: SPR-16160

(cherry picked from commit 80a0cf7)
2017-11-14 12:26:32 +01:00
Juergen Hoeller 9ca4de1ccf MockHttpServletRequest.getRequestURL aligns with getServerName/Port
Issue: SPR-16138

(cherry picked from commit 0edf4d6)
2017-11-14 12:25:55 +01:00
Juergen Hoeller 519195cf66 AbstractApplicationContext silently ignores non-initialized ApplicationEventMulticaster/LifecycleProcessor on destruction
Issue: SPR-16149

(cherry picked from commit 1611ce7)
2017-11-14 12:25:30 +01:00
Juergen Hoeller 573ff2c58d ClassPathResource uses specific constructors in createRelative
Issue: SPR-16146

(cherry picked from commit d00e4f1)
2017-11-14 12:25:18 +01:00
Rossen Stoyanchev 9470719cdb Support charset config by (static) resource location
This commit adds support for configuring static resource locations
with a charset to be applied to relative paths.
2017-11-09 14:51:49 -05:00
Rossen Stoyanchev 97bc2762e1 Handle errors via AsyncListener
This is a limited backport of commit #e0678b mainly providing the fix without
exposing the onError callbacks.

Issue: SPR-16058
2017-11-08 23:10:16 -05:00
Juergen Hoeller 5867ea0c3c Correct SpEL example (matching its comment)
Issue: SPR-16111
2017-10-27 11:31:03 +02:00
Juergen Hoeller 9cc3349e2d Introspect interface-declared methods in case of proxy (for varargs)
Issue: SPR-16122

(cherry picked from commit 419b444)
2017-10-27 11:30:52 +02:00
Juergen Hoeller 8904de2149 Drive letter case alignment in addClassPathManifestEntries
Issue: SPR-16117

(cherry picked from commit a2f5e12)
2017-10-27 11:30:43 +02:00
Juergen Hoeller 4208ec0ba8 Polishing
(cherry picked from commit 7e8c8f0)
2017-10-27 11:30:34 +02:00
Juergen Hoeller ab19c227d3 DefaultResponseErrorHandler.hasError tolerates unknown status codes
Issue: SPR-16108
2017-10-24 15:44:37 +02:00
Juergen Hoeller be5b9354a9 Polishing 2017-10-24 14:34:56 +02:00
Juergen Hoeller c92393b168 Compatibility with OpenPDF as alternative to iText 2.1.7
Issue: SPR-16107

(cherry picked from commit 9efdadc)
2017-10-24 14:34:37 +02:00
Juergen Hoeller 75a813aff6 WebSphereUowTransactionManager logs overridden application exceptions
Issue: SPR-16102

(cherry picked from commit efe943d)
2017-10-24 14:34:00 +02:00
Juergen Hoeller 6446ffd063 BridgeMethodResolver properly resolves interface hierarchies
Issue: SPR-16103

(cherry picked from commit 182da15)
2017-10-24 14:33:19 +02:00
Juergen Hoeller db7d71503d Polishing 2017-10-23 19:03:56 +02:00
Juergen Hoeller 99d39eb2ee Avoid temporary String creation in StringUtils.starts/endsWithIgnoreCase
Issue: SPR-16095
2017-10-23 19:03:42 +02:00
Juergen Hoeller c32c9ecb61 Explicit notes on advice mode proxy vs aspectj
Issue: SPR-16092
2017-10-23 19:03:36 +02:00
Juergen Hoeller 40f3fb20c2 SchedulingConfigurer and JmsListenerConfigurer respect @Order
Issue: SPR-16090
2017-10-23 19:03:30 +02:00
Juergen Hoeller 268ccb6b6b SubProtocolWebSocketHandler provides protected decorateSession method
Issue: SPR-16089
2017-10-23 19:03:24 +02:00
Haruki Okada 9c7141a24a Fix wrong javadoc example
Closes gh-1575
2017-10-23 09:21:10 +02:00
Juergen Hoeller b0ae8f6058 ModelAttributeMethodProcessor detects re-enabled binding declaration
Issue: SPR-16083

(cherry picked from commit bec1fc1)
2017-10-18 13:29:41 +02:00
Juergen Hoeller d473506d32 Explicit notes on ExceptionHandler root vs cause resolution
Issue: SPR-16074

(cherry picked from commit ea00c7c)
2017-10-18 13:28:59 +02:00
Juergen Hoeller 6f65b638de Defensive resolution of getParameterType (actually never returning null)
Covers use of ResolvableType in overridden getParameterType variants.

Issue: SPR-16072
2017-10-17 12:15:51 +02:00
Juergen Hoeller 97c63857c4 Allow PropertyEditor conversion as fallback for enums
Issue: SPR-16082

(cherry picked from commit ef6aef9)
2017-10-17 12:15:37 +02:00
Drummond Dawson 4cc8f4c4d8 Missing some double backticks with apostrophes
Closes gh-1566
2017-10-17 08:35:24 +02:00
Juergen Hoeller dff2c84ed1 Clarify destroy method suppression for DisposableBean vs (Auto)Closeable
Issue: SPR-16078
2017-10-16 23:11:19 +02:00
Juergen Hoeller 17fb4fed09 Extended coverage of full vs lite mode for configuration classes
Issue: SPR-16076
2017-10-16 23:02:35 +02:00
Juergen Hoeller 77bab959a3 Polishing 2017-10-16 19:59:34 +02:00
Juergen Hoeller c2438cb932 Defensive resolution of getParameterType (actually never returning null)
Includes defensive access to volatile field for resolved parameter type.

Issue: SPR-16072
2017-10-16 19:59:07 +02:00
Juergen Hoeller 03be8095ca Consistent handling of null array for arguments
Issue: SPR-16075

(cherry picked from commit c29b6f5)
2017-10-16 19:58:49 +02:00
Spring Buildmaster 4daf685eee Next Development Version 2017-10-10 13:54:37 +00:00
Rossen Stoyanchev b6ca8a9018 HandlerMappingIntrospector is a bean 2017-10-09 10:44:38 -04:00
Juergen Hoeller 8071f13481 Upgrade to OpenJPA 2.4.2 2017-10-09 15:41:28 +02:00
Juergen Hoeller 565b20d638 Polishing 2017-10-09 15:41:10 +02:00
Juergen Hoeller 7610210a0e Consistently sort BeanDefinitionRegistryPostProcessors
Issue: SPR-16043

(cherry picked from commit ad4c8e7)
2017-10-09 15:40:04 +02:00
Juergen Hoeller a4803d8b0f Convenient forType methods for ParameterizedTypeReference
Issue: SPR-16054

(cherry picked from commit 53091c7)
2017-10-09 15:39:07 +02:00
Juergen Hoeller ab081c4fab Latest applicable dependency updates (Gson 2.8.2, Rome 1.7.4, Netty 4.1.16, Tomcat 8.5.23) 2017-10-04 13:20:05 +02:00
Juergen Hoeller dbc04282e2 Polishing 2017-10-04 13:18:39 +02:00
Juergen Hoeller bb41ccefc0 Deprecate HibernateJpaSessionFactoryBean (against Hibernate 5.2)
Issue: SPR-16016

(cherry picked from commit 66a6fda)
2017-10-04 13:18:17 +02:00
Juergen Hoeller d0d4421aea Tokenizer uses single process step and length-based exhaustion check
Issue: SPR-16032

(cherry picked from commit 03b6828)
2017-10-04 13:18:04 +02:00
Tom Fitzhenry 1a1d767d59 Fix typo in exception message: quite -> quiet
Closes gh-1547
2017-10-03 08:25:27 +02:00
Robin Wang 1bf3e7c021 Fix typo
Closes gh-1545
2017-10-01 09:23:47 +02:00
Juergen Hoeller 40ba95f82e Consistent configurer access in WebMvcConfigurationSupport
Issue: SPR-16017
2017-09-27 19:00:51 +02:00
Juergen Hoeller cc70fdcbeb Backport further refinements from the nullability efforts
Issue: SPR-15656
2017-09-27 15:20:17 +02:00
Juergen Hoeller 5f167fd7f8 Polishing 2017-09-27 01:46:16 +02:00
Juergen Hoeller 9fdc4404a5 Backport selected refinements from the nullability efforts
Issue: SPR-15656
2017-09-27 00:10:04 +02:00
Juergen Hoeller 18a3322d2f Lenient tolerance of unknown HTTP status codes behind RestTemplate
Issue: SPR-15978
2017-09-27 00:09:42 +02:00
Juergen Hoeller 87df393f91 MockPart backport
Issue: SPR-15854
2017-09-27 00:09:09 +02:00
Juergen Hoeller 963dd3f804 Clarify @Bean return type recommendation in case of multiple interfaces
Issue: SPR-15973
2017-09-27 00:09:00 +02:00
Juergen Hoeller 8e3a55ba89 Latest applicable dependency updates (Tomcat 8.5.21, JRuby 1.7.27, Rhino 1.7.7.2, WebJars Locator 0.32-1) 2017-09-27 00:08:54 +02:00
Juergen Hoeller a839477d4a Explicit check for duplicates in addClassPathManifestEntries
Issue: SPR-15989

(cherry picked from commit 9d8e3d4)
2017-09-27 00:08:12 +02:00
Juergen Hoeller 53a9697ff1 Consistent conversion of Optional array/list arrangements
Issue: SPR-15918
Issue: SPR-15919
Issue: SPR-15676

(cherry picked from commit 15c82af)
2017-09-27 00:07:55 +02:00
Juergen Hoeller d11bd64e0d TaskExecutorRegistration does not apply its default settings to a user-provided executor
Also, ChannelRegistration.setInterceptors is deprecated now: in favor of a fluently named interceptors(...) method which is documented to add the given interceptors to the channel's current list.

Issue: SPR-15962
Issue: SPR-15976

(cherry picked from commit ac9cfef)
2017-09-26 23:58:57 +02:00
Juergen Hoeller dedecb9daa HttpEntityMethodProcessor lets entity headers override existing headers (again)
Issue: SPR-15952

(cherry picked from commit 5bdcb89)
2017-09-26 23:58:49 +02:00
Stephane Nicoll 35af7ff854 Reuse JmsTemplate's MessageConverter in JmsMessagingTemplate
This commit makes sure that any custom MessageConverter set in a
JmsTemplate used by a JmsMessagingTemplate is reused as the payload
converter of the message.

Issue: SPR-15965

(cherry picked from commit b275a06)
2017-09-26 23:58:03 +02:00
Xavier Downs 5e904ddcaa Fix Javadoc typo
Closes gh-1531
2017-09-20 09:33:42 +02:00
Spring Buildmaster 74532a24a4 Next Development Version 2017-09-11 08:17:11 +00:00
Juergen Hoeller c0ee1ff896 Javadoc syntax fixes 2017-09-10 21:08:03 +02:00
Juergen Hoeller f944815d92 Ignore Hibernate Validator style ".<collection element>" suffix for field path
Issue: SPR-15916
2017-09-10 20:48:49 +02:00
Juergen Hoeller 0d0399ac02 Defensively ignore AbstractMethodError from parameterNameProvider
Issue: SPR-15856
2017-09-10 20:48:25 +02:00
Juergen Hoeller d1f42ac729 Unwrap Validator proxy for access to forExecutables (if necessary)
Issue: SPR-15807
2017-09-10 20:47:57 +02:00
Juergen Hoeller 17f42fc97a Polishing 2017-09-08 19:42:32 +02:00
Juergen Hoeller fa2c377405 Downgrade to AspectJ 1.8.9 and merge EhCache 3 tests into spring-context-support
Includes latest applicable updates (Jackson 2.8.10, OkHttp 3.8.1, Undertow 1.3.31, Netty 4.1.15)

Issue: SPR-15836
Issue: SPR-15880
2017-09-08 19:41:27 +02:00
Juergen Hoeller 9dcdfec2e2 Properly retrieve and expose HttpServletResponse for async requests
Issue: SPR-15867
2017-09-08 19:40:46 +02:00
Juergen Hoeller 07a0a31565 Heart-beat log message potentially without session id
Issue: SPR-15937
(cherry picked from commit aa4ae7a)
2017-09-08 19:39:05 +02:00
Juergen Hoeller f3a2f57696 SimpleAsyncTaskExecutor properly respects NO_CONCURRENCY
Issue: SPR-15895
(cherry picked from commit 204ddeb)
2017-09-08 19:38:59 +02:00
Juergen Hoeller 80bf394fdc @Lazy falls back to empty map/list/set for non-required collection dependency
Issue: SPR-15858
(cherry picked from commit ec1eafc)
2017-09-08 19:38:53 +02:00
Juergen Hoeller f948742781 Leniently handle lambda-defined listeners with ErrorHandler as well
Issue: SPR-15838
(cherry picked from commit dd2bbcb)
2017-09-08 19:38:46 +02:00
Juergen Hoeller 0088922dfd checkConfigurationClassCandidate explicitly skips factory method definitions
Issue: SPR-14603
(cherry picked from commit 1fbd047)
2017-09-08 19:38:19 +02:00
Juergen Hoeller 57fbdc0ad5 Consistent logging in Environment and PropertySource implementations
Issue: SPR-15825
(cherry picked from commit fac83b2)
2017-09-08 19:38:03 +02:00
Brian Bohl f5d689e764 Fix StringIndexOutOfBoundsException in RestTemplate
Backport for commits #81dfad and #3d61f7

Issue: SPR-15900
2017-09-01 17:00:23 -04:00
Rossen Stoyanchev 681ced8fd3 Cancel WebAsyncManager thread on request timeout
Issue: SPR-15852
2017-08-16 09:42:39 +02:00
Rossen Stoyanchev 8b64ad3192 Use exact type name in doc sample
Issue: SPR-15863
2017-08-15 14:45:57 +02:00
Rossen Stoyanchev 35248498ae Fix regression in HttpPutFormContentFilter
Re-arrange the checks so that if there is no form parameter, then
immediately and unconditionally delegate to super.getParameterValues().
Or reversely if there is no super.getParameterValues() then return the
form parameter.

So the only remaining case is when combining values present in both.
In that case we'll take both only if a queryString exists.

One extra fix is to not even wrap the request if we did not parse any
form parameters at all which can happen with HttpHiddenMethodFilter.

Issue: SPR-15828, 15835
2017-08-01 12:41:45 +02:00
Rossen Stoyanchev 5f07434360 Improve check for "Broken pipe" error message
Issue: SPR-15802
2017-07-25 10:34:30 +02:00
Rossen Stoyanchev cd602e5904 Deprecate setContentDispositionFormData method
The method was orginally added under SPR-14547 but the example in it
was probably intended for use with Content-Disposition server response
header (file download) and not for a Content-Disposition header
within the body of a multipart request.

In a Spring application a multipart request is typically serialized
by the FormHttpMessageConverter and hence the Content-Disposition is
not explicitly set by the application.
2017-07-20 17:58:52 +02:00
Spring Buildmaster 0e8bd71d53 Next Development Version 2017-07-20 11:57:27 +00:00
Juergen Hoeller c752ba5b38 Polishing 2017-07-19 23:55:47 +02:00
Juergen Hoeller 12978b8185 Ignore (Auto)Closeable for interface-based proxy decisions
Issue: SPR-15779
(cherry picked from commit 118d147)
2017-07-19 23:55:18 +02:00
Juergen Hoeller 40b4276475 UriUtils.extractFileExtension properly handles all fragments
Issue: SPR-15786
(cherry picked from commit 13080f0)
2017-07-19 23:54:57 +02:00
Rossen Stoyanchev 4160ced64c Backport of relative redirect filter support
Issue: SPR-15717
2017-07-19 23:54:32 +02:00
Juergen Hoeller a032e86355 Explicit error message for bean name clash with containing configuration class
Issue: SPR-15775
(cherry picked from commit bca5a36)
2017-07-19 23:54:04 +02:00
Juergen Hoeller 4b2bad96ce Polishing
(cherry picked from commit efc5b47)
2017-07-14 17:41:26 +02:00
Juergen Hoeller 1513c4a952 Expression javadoc alignment
(cherry picked from commit 1ad6180)
2017-07-14 17:12:50 +02:00
Juergen Hoeller bb6d9fabee Expression alignment and related polishing (backported from master) 2017-07-14 15:41:38 +02:00
Juergen Hoeller bffcd33ea3 PropertyOrFieldReference checks cached PropertyAccessor against current EvaluationContext
Issue: SPR-15769
(cherry picked from commit bcf9f21)
2017-07-14 15:40:52 +02:00
Juergen Hoeller c9ffa64140 DefaultListableBeanFactory falls back to empty DLBF instance on deserialization
Issue: SPR-15766
2017-07-13 13:02:29 +02:00
Juergen Hoeller aa0d7a61b6 AbstractTraceInterceptor provides logExceptionStackTrace flag and writeToLog delegates
Issue: SPR-15763
2017-07-13 13:01:35 +02:00
Juergen Hoeller e138d7d29f Page-level JSTL time zone support for JSP tags
Issue: SPR-15746
2017-07-12 22:59:42 +02:00
Juergen Hoeller 50f8b6b3ab Revised assertions and $[invocationTime] support for exceptionMessage
Issue: SPR-15763
(cherry picked from commit 19a8efc)
2017-07-12 22:59:34 +02:00
Juergen Hoeller 121a3bf670 Always invoke Jackson serialization with AtomicReference cause
Issue: SPR-15760
(cherry picked from commit 5f767a8)
2017-07-12 22:59:29 +02:00
Juergen Hoeller e4031f290e Efficient log checks in STOMP encoder/decoder
(cherry picked from commit 122ee30)
2017-07-12 22:59:18 +02:00
Juergen Hoeller 55fa5f2b65 ReflectionTestUtils does not require spring-aop on the classpath
Issue: SPR-15757
(cherry picked from commit dd43b6a)
2017-07-12 22:59:12 +02:00
Juergen Hoeller 3802aca474 LinkedCaseInsensitiveMap exposes its locale for key conversion
Issue: SPR-15752
(cherry picked from commit 9b5132c)
2017-07-12 22:59:03 +02:00
Juergen Hoeller a9a4d7cf78 Perform onException delegation outside of connection monitor
Issue: SPR-15738
(cherry picked from commit 6d55b3a)
2017-07-12 22:58:53 +02:00
Juergen Hoeller 17382aec6d AbstractValueAdaptingCache subclasses may reuse NullValue.INSTANCE
Issue: SPR-15693
(cherry picked from commit 59c26f6)
2017-07-12 22:58:40 +02:00
Juergen Hoeller 8ad3c958e1 Reliably detect event listener conditions on proxied beans
Issue: SPR-15678
(cherry picked from commit eb928ce)
2017-07-12 22:58:34 +02:00
Rossen Stoyanchev 8d743181da Fix MockMvc + HttpPutFormContentFilter issue
Issue: SPR-15753
2017-07-11 12:03:07 +02:00
Juergen Hoeller f92ab75bc9 Latest dependency updates (AspectJ 1.8.10, Gson 2.8.1, Commons FileUpload 1.3.3, JsonPath 2.3) 2017-07-05 11:25:39 +02:00
Juergen Hoeller 092b5f7556 Clarified role of postProcessAfterInstantiation
Issue: SPR-15732
2017-07-05 11:23:34 +02:00
Brian Clozel d4d609318d Include port info in HTTP headers for Netty client
This commit adds the port information in the "Host" HTTP request header
for the Netty-based HTTP client.

Issue: SPR-15706
(cherry-picked from commit baaa84e90)
2017-07-04 12:19:54 +02:00
Juergen Hoeller 501891c749 FactoryBean object cache cleared on shutdown
Issue: SPR-15722
(cherry picked from commit 6534359)
2017-06-30 21:01:09 +02:00
Juergen Hoeller 2b0dc8d7ff Upgrade to Objenesis 2.6
Includes latest dependency updates (Groovy 2.4.12, Jackson 2.8.9, Jetty 9.4.6, Netty 4.1.12, Tomcat 8.5.16)

Issue: SPR-15600
2017-06-30 16:07:52 +02:00
Juergen Hoeller 674e2320a8 CronSequenceGenerator.isValidExpression actually validates cron fields
Issue: SPR-15604
(cherry picked from commit 5f4d1a4)
2017-06-30 16:07:30 +02:00
Juergen Hoeller fee259a3c5 WebAsyncManager defensively ignores attribute type mismatch
Issue: SPR-15709
(cherry picked from commit c4694c3)
2017-06-30 16:07:14 +02:00
Juergen Hoeller 016b7d753c Fine-tune HTTP/RMI Invoker exception handling
Issue: SPR-15684
(cherry picked from commit 535103c)
2017-06-30 16:06:53 +02:00
Juergen Hoeller a17255a2e3 SimpleRequestExpectationManager properly handles sequential requests with different count
Issue: SPR-15672
(cherry picked from commit efb735a)
2017-06-30 16:06:39 +02:00
Juergen Hoeller 35efdf6b51 HttpComponentsAsyncClientHttpRequestFactory supports plain HttpAsyncClient as well
Issue: SPR-15664
(cherry picked from commit 7b5f96c)
2017-06-30 16:06:26 +02:00
Juergen Hoeller b35c238d27 Cleanup of duplicate semicolons
Issue: SPR-15654
(cherry picked from commit 779deb0)
2017-06-30 16:06:05 +02:00
Spring Buildmaster db1fd516ea Next Development Version 2017-06-07 19:29:40 +00:00
Juergen Hoeller b7337b304e Correct native Validator reference for fallback in SpringValidatorAdapter
Issue: SPR-15629
2017-06-07 18:40:52 +02:00
Juergen Hoeller 7cac1f1e6e Latest applicable dependency updates (Netty 4.1.11, Tomcat 8.5.15, Undertow 1.3.30) 2017-06-07 17:56:58 +02:00
Juergen Hoeller fa09cd3737 Avoid inefficient keySet iteration in messaging classes
Issue: SPR-15553
2017-06-07 17:56:51 +02:00
Juergen Hoeller be93ee77e4 Debug-level log entry for any Jackson exception during canConvert
Issue: SPR-15582
2017-06-07 17:56:47 +02:00
Juergen Hoeller 8330134757 Unwrap SpringValidatorAdapter (e.g. CustomValidatorBean) to native Validator
Issue: SPR-15629
2017-06-07 17:56:42 +02:00
Juergen Hoeller 9cb9884533 Consistently accept "taskExecutor" bean of type Executor (as stated in @EnableAsync's javadoc)
Issue: SPR-15566
(cherry picked from commit 3cc94ae)
2017-06-07 17:56:36 +02:00
Juergen Hoeller ac25db6d2b LocalValidatorFactoryBean properly supports unwrap at ValidatorFactory level
Issue: SPR-15561
(cherry picked from commit cb3d1be)
2017-06-07 17:56:31 +02:00
Juergen Hoeller 22bf9febcc Close InputStreams in writeResourceRegionCollection (analogous to writeResourceRegion)
Issue: SPR-15559
(cherry picked from commit eaac348)
2017-06-07 17:56:21 +02:00
Juergen Hoeller c6deeb31ec ResourceUtils.extractArchiveURL properly deals with top-level war URLs
Issue: SPR-15556
(cherry picked from commit 7b3f5fd)
2017-06-07 17:56:16 +02:00
Juergen Hoeller f80b2d9a94 Revised png and jpeg mappings
Issue: SPR-15546
Issue: SPR-15557
(cherry picked from commit e835f4d)
2017-06-07 17:56:09 +02:00
Rossen Stoyanchev 8c206bf477 Improve docs on forwarded headers
Issue: SPR-15612
2017-06-01 22:37:34 -04:00
Christoph Dreis 6aeb8ef56d Optimize DefaultUserDestinationResolver.resolveDestination()
Issue: SPR-15602
2017-06-01 16:08:49 -04:00
Rossen Stoyanchev 04a96ffa27 Add removeOnly mode to ForwardedHeaderFilter
Issue: SPR-15610
2017-06-01 15:48:39 -04:00
Jay Bryant 2677584658 Add introductory paragraphs where missing
Issue: SPR-15585
2017-05-25 12:06:45 -04:00
Rossen Stoyanchev 99236759ec ExceptoinWebSocketHandlerDecorator uses ERROR level
Issue: SPR-15537
2017-05-24 15:01:36 -04:00
skarafaz e2aa117ff9 Find exact matches in WebJarsResourceResolver
Prior to this commit, resolving resources from webjars using the
`WebJarAssetLocator.getFullPath` could lead to multiple candidates,
since this method is trying to find *any* resource matching that path
under the given webjar location.

This commit replaces that call with
`WebJarAssetLocator.getFullPathExact`, which avoids those multiple
matches and only resolves resources if the given path is exact.

Issue: SPR-15526
2017-05-24 10:45:38 +02:00
Rossen Stoyanchev 8deec9569c Protect against NPE in DefaultSubscriptionRegistry
Follow-up fix on the recent commit:
https://github.com/spring-projects/spring-framework/commit/4fc41e

Issue: SPR-15543
2017-05-22 16:12:49 -04:00
Andrey Kaipov 0f8bf10aa8 Minor typo fix: form -> from
Closes gh-1411
2017-05-20 14:50:47 +02:00
Martin Švorc e0a7b074ed Use original query string of forwarded request
Prior to this commit, the AbstractFlashMapManager has used the
originating URI but the query string of the forwarded request. That
resulted to FlashMap not being matched even when both originating
URI and query string matched the FlashMap attributes. The originating
query string is now used to match the forwarded request.

Issue: SPR-15505
2017-05-19 17:07:17 -04:00
Bao Tran 4fc41eeeb9 Fix duplicate STOMP subscription id issue
Issue: SPR-15543
2017-05-19 15:15:01 -04:00
Juergen Hoeller 81143a80c4 Wrap IOException as HttpMessageNotReadableException for RestTemplate usage
In the 4.3.x line, conversion exceptions do not get wrapped as RestClientException yet, so the expectation remains to receive a HttpMessageNotReadableException for conversion-level IOExceptions.

Issue: SPR-13592
2017-05-08 08:42:06 +02:00
Juergen Hoeller 9572859a35 Expect IOException instead of HttpMessageNotReadableException 2017-05-07 22:10:55 +02:00
Juergen Hoeller 78931ee3ea Polishing 2017-05-07 21:41:26 +02:00
Juergen Hoeller e522fec611 HandlerExecutionChain.toString() includes reliable interceptor number
Issue: SPR-15525
(cherry picked from commit 92f18a4)
2017-05-07 21:26:01 +02:00
Juergen Hoeller a12bbde87e Latest dependency updates (EhCache 2.10.4 & 3.1.4, Groovy 2.4.11, Jetty 9.4.5, Netty 4.1.10, OkHttp 3.7, Rome 1.7.2, Tomcat 8.5.14) 2017-05-04 14:16:24 +02:00
Juergen Hoeller 50235be746 Avoid JDK 7+ AssertionError constructor in 4.3.x line 2017-05-04 14:14:56 +02:00
Juergen Hoeller 1332482c40 Polishing 2017-05-04 14:09:15 +02:00
Juergen Hoeller 799589ec1c Revised javadoc
Issue: SPR-15466
2017-05-04 14:08:14 +02:00
Juergen Hoeller 16fdda00c1 Debug log messages for value retrieval exceptions
Issue: SPR-15481
2017-05-04 14:08:00 +02:00
Juergen Hoeller d2985613d1 Proper resolution of Tomcat war URL
Issue: SPR-15485
(cherry picked from commit d43dfc7)
2017-05-04 14:07:14 +02:00
Juergen Hoeller beac891ff0 Honor @Autowired(required=false) at parameter level
Issue: SPR-15268
(cherry picked from commit d74542e)
2017-05-04 14:07:07 +02:00
Juergen Hoeller 2d1b551248 Common root cause introspection algorithm in NestedExceptionUtils
Issue: SPR-15510
(cherry picked from commit 9d8e9cf)
2017-05-04 14:05:03 +02:00
Juergen Hoeller aa8cf190d3 Property actually throws exception for no write method found
Issue: SPR-15507
(cherry picked from commit 817e80c)
2017-05-04 14:03:30 +02:00
Juergen Hoeller d643e57318 ResolvableType.clearCache() clears SerializableTypeWrapper cache as well
Issue: SPR-15503
(cherry picked from commit 7ca0094)
2017-05-04 14:03:22 +02:00
Juergen Hoeller 84d2e5a3c8 Optimize AntPathMatcher when checking for potential matches
Issue: SPR-15477
(cherry picked from commit baa7b1c)
2017-05-04 14:02:43 +02:00
Juergen Hoeller dab56dbb05 GenericFilterBean lazily initializes its default environment
Alignment with HttpServletBean; consistent use of EnvironmentCapable.

Issue: SPR-15469
(cherry picked from commit 1ea54eb)
2017-05-04 14:01:09 +02:00
Juergen Hoeller 9b647021f7 Allow for HttpOnly cookie result matcher
Issue: SPR-15488
(cherry picked from commit 04f0f13)
2017-05-04 14:00:37 +02:00
Juergen Hoeller 38089d8e66 Correct attributeHasNoErrors message in ModelResultMatchers
Includes consistent name quoting.

Issue: SPR-15487
(cherry picked from commit 0479dc9)
2017-05-04 14:00:15 +02:00
Gregory Vandenbroucke 554c3f3d7e Full "Forwarded" header support including port number
Issue: SPR-15504
2017-05-02 17:00:48 -04:00
Phillip Webb ee40310c92 Defer Charset.availableCharsets() call
Change the `StringHttpMessageConverter` to defer calling
Charset.availableCharsets() until absolutely necessary to help improve
startup times.

Issue: SPR-15502
2017-05-02 17:19:19 +02:00
Stephane Nicoll 226cddadef Add getTargetDataSource to TransactionAwareCacheDecorator
Issue: SPR-15479
2017-04-27 11:36:43 +02:00
Stephane Nicoll 5a80f4f16e Polish 2017-04-27 11:36:35 +02:00
John Ryan bb63ce9935 Remove extraneous asterisk
Closes gh-1397
2017-04-21 09:48:56 +02:00
Fredrik Sundberg 1b4289803b Fix Selenium links in testing.adoc
Selenium wiki & javadoc moved from google code to github.
Also a fix to a link for Geb.

Closes gh-1392
2017-04-19 09:23:14 +02:00
Spring Buildmaster 3d7576df7f Next Development Version 2017-04-18 14:46:26 +00:00
Juergen Hoeller 8b9e9202f1 Upgrade to Hibernate ORM 5.2.10 2017-04-17 19:42:10 +02:00
Juergen Hoeller afe11e7919 Revised logging documentation for the 4.3.x line 2017-04-17 19:41:59 +02:00
Juergen Hoeller 665e6cf6ca Refined log message for interface-implementing method
Issue: SPR-15436
2017-04-17 19:29:01 +02:00
Juergen Hoeller fd1d8aeeb4 Polishing
(cherry picked from commit 91df065)
2017-04-17 15:39:06 +02:00
Juergen Hoeller 9b2f9e655e CglibAopProxy logs explicit warning for interface-implementing method marked as final
Issue: SPR-15436
(cherry picked from commit 0d0b879)
2017-04-17 15:38:59 +02:00
Juergen Hoeller 6c370ed28d Recommendation for consistent @Profile declarations on overloaded @Bean methods
Issue: SPR-15266
(cherry picked from commit 5d3249f)
2017-04-17 15:38:53 +02:00
Juergen Hoeller a2b356162e Explicitly replace target ApplicationListener with singleton proxy, if any (avoiding double registration/invocation)
Issue: SPR-15452
(cherry picked from commit 9abf249)
2017-04-17 15:38:46 +02:00
Stephane Nicoll 71f7fdd632 Polish "Improve unless condition in caching doc"
Closes gh-1387
2017-04-13 17:51:20 +02:00
Michael J. Simons c35ddf905a Improve unless condition in caching doc
See gh-1387
2017-04-13 17:51:12 +02:00
Michael J. Simons d866715556 Polish condition in caching examples
Closes gh-1386
2017-04-13 17:51:02 +02:00
Juergen Hoeller a9a1f783c5 Polishing 2017-04-13 15:59:15 +02:00
Juergen Hoeller 65d52a4b97 Correctly process Postgresql ?| and ?& operator
Issue: SPR-15382
2017-04-13 15:59:07 +02:00
Juergen Hoeller 3c8fc46568 Backported JSON converter alignment (supports method, exception messages)
Includes deprecation of getTypeToken method in GsonHttpMessageConverter.

Issue: SPR-15381
2017-04-13 15:58:53 +02:00
Juergen Hoeller 421fabb2c4 Configurable locale/timezone attribute name for SessionLocaleResolver
Issue: SPR-15450
(cherry picked from commit cec36fe)
2017-04-13 15:56:07 +02:00
Juergen Hoeller 811d523211 FreeMarkerConfigurationFactory falls back to SpringTemplateLoader on any exception
Issue: SPR-15445
(cherry picked from commit a55a0f2)
2017-04-13 15:56:01 +02:00
Juergen Hoeller 40232f4e22 ASM annotation visitor defensively accesses enum constants
Issue: SPR-15442
(cherry picked from commit 4838f06)
2017-04-13 15:55:53 +02:00
Juergen Hoeller 80fa3ac907 ShadowingClassLoader can be constructed without default excludes
Issue: SPR-15439
(cherry picked from commit 1735ba2)
2017-04-13 15:55:44 +02:00
Juergen Hoeller 54180f90e2 UnknownHostException as resource-not-found for properties files
Plus first-class declaration of FileNotFoundException in Resource javadoc.

Issue: SPR-15433
(cherry picked from commit c4e0d6c)
2017-04-13 15:55:29 +02:00
Juergen Hoeller 865953f145 Optimize StringUtils.replace/deleteAny for common no-op case
Issue: SPR-15430
(cherry picked from commit ce4eff3)
2017-04-13 15:55:11 +02:00
Juergen Hoeller 93fac8882f Undeprecate TypeVariableMap methods on GenericTypeResolver
Issue: SPR-15429
(cherry picked from commit 7fbc20e)
2017-04-13 15:55:02 +02:00
Juergen Hoeller a3d199f4dd AcceptHeaderLocaleResolver returns default locale in case of no supported locale found
Issue: SPR-15426
(cherry picked from commit ea98ee8)
2017-04-13 15:54:46 +02:00
Juergen Hoeller 597fe0720f HandlerMethod evaluates ResponseStatus annotation for early caching
Issue: SPR-15227
(cherry picked from commit 5986f88)
2017-04-13 15:54:35 +02:00
Juergen Hoeller 8321f01bf8 SettableTask.checkCompletingThread() only resets marker after match
Issue: SPR-15409
(cherry picked from commit 8cb24e0)
2017-04-13 15:54:22 +02:00
Juergen Hoeller 7e736b69b7 UrlResource applies StringUtils.getFilename against cleaned URL path
Issue: SPR-15411
(cherry picked from commit 702e01a)
2017-04-13 15:54:03 +02:00
Juergen Hoeller 8b054840fc Minimize reflective interaction with annotation instances during retrieval
Issue: SPR-15387
(cherry picked from commit 3037277)
2017-04-13 15:53:46 +02:00
Juergen Hoeller 7f3d0b3e6e Test for BeanPropertySqlParameterSource with collection
Issue: SPR-15390
(cherry picked from commit af6f688)
2017-04-13 15:53:39 +02:00
Rossen Stoyanchev 546d7ddd07 Update @ControllerAdvice Javadoc
Issue: SPR-15432
2017-04-12 17:53:42 -04:00
Rob Winch 95099fd709 Fix ForwardedHeaderFilter preserves semicolon content
Previously a requestURI that contained ';' would have the value incorrectly stripped out when using
ForwardedHeaderFilter.

This commit ensures that the ';' is preserved when using ForwardedHeaderFilter.

Issue: SPR-15428
2017-04-10 09:15:15 -05:00
Rob Winch f65e1edd58 Polish
Group all contextPath tests together
2017-04-10 09:15:07 -05:00
Rob Winch 0a9f98f0df Add test to ensure ForwardedHeaderFilter contextPath preserves encoding
Add a test to verify that the ForwardedHeaderFilter contextPath override preserves URL encoding
as it should.

Issue SPR-15422
2017-04-10 09:13:41 -05:00
Rob Winch 46cf4f9ba1 ForwardedHeaderFilter requestURI preserve encoding
Previously ForwardedHeaderFilter would override the requestURI with a URL decoded value. This would cause
problems when using a URL encoded requestURI since downstream Filters would not see the URL encoded
value as they should.

This commit resolves this issue by ensuring that the requestURI is properly encoded.

Issues SPR-15422
2017-04-10 09:11:08 -05:00
Kirill Gavrilov 2b930e3858 Fix typo
Closes gh-1383
2017-04-10 09:54:44 +02:00
Stephane Nicoll bde2ddbeb1 Update copyright header
Closes gh-1382
2017-04-09 09:48:47 +02:00
John S. Ryan 4eb929c105 Fix typo in AfterReturningAdviceInterceptor JavaDoc
See gh-1382
2017-04-09 09:48:38 +02:00
Bryan Kelly d0d7a88233 Fix ForwardedHeaderFilter getRequestURL()
Previously ForwardedHeaderFilter would return the same StringBuffer for every invocation. This
meant that users that modified the StringBuffer changed the state of the HttpServletRequest.

This commit ensures that a new StringBuffer is always returned for ForwardedHeaderFilter.

Issue: SPR-15423
2017-04-07 15:45:23 -05:00
Rossen Stoyanchev f7548a87ed Deprecations related to reactive type support in 5.0
Issue: SPR-15365
2017-04-03 09:26:46 -04:00
QBNemo e0fe7cdc44 Fix typo
Closes gh-1354
2017-03-27 10:12:53 +02:00
Connor Lin 8289bf0aff Remove a redundant word
Closes gh-1361
2017-03-27 10:10:14 +02:00
Grant Hutchins 79d747410d Fix typo
Closes gh-1364
2017-03-27 10:05:49 +02:00
Brian Clozel 70bca99da8 VersionResourceResolver should delegate to the chain
Prior to this commit, the `VersionResourceResolver` implementation of
`resolveUrlPathInternal` would delegate to the resolver chain but would
never use the give result if the current request didn't match a
configured version strategy pattern.

This is a problem if the resolver supposed to resolve the resource path
is configured after a `VersionResourceResolver` in the resolver chain;
this means that other resolver never gets to participate in the result
of the chain.

Issue: SPR-15372
(cherry picked from commit fdd5031)
2017-03-24 14:27:29 +01:00
Juergen Hoeller 83617f382c Latest dependency updates (Hibernate ORM 5.2.9, Hibernate Validator 5.2.5, Undertow 1.3.28, Jetty 9.4.3, Joda-Time 2.9.9) 2017-03-24 13:41:57 +01:00
Juergen Hoeller 21ac764e5c Polishing 2017-03-24 13:41:34 +01:00
Juergen Hoeller c4fda0e811 Up-to-date guidelines for serialization-based endpoints
Issue: SPR-15317
(cherry picked from commit 2236262)
2017-03-24 13:41:19 +01:00
Juergen Hoeller 66670cfd56 Clarification: Spring AOP pointcuts may match non-public methods
Issue: SPR-15354
(cherry picked from commit b90d3d0)
2017-03-24 13:41:08 +01:00
Juergen Hoeller c31bfe65aa Drop outdated DeferredQueryInvocationHandler.finalize() implementation
Issue: SPR-15363
(cherry picked from commit b2a6a57)
2017-03-24 13:40:58 +01:00
Juergen Hoeller 22ddb35258 HeaderValueHolder.toString() exposes underlying list of header values
Issue: SPR-15375
(cherry picked from commit 15bff8f)
2017-03-24 13:40:43 +01:00
Juergen Hoeller d0177b0f55 Revised supportedMethods null handling in HttpRequestMethodNotSupportedException
Issue: SPR-15377
(cherry picked from commit 5ea4abd)
2017-03-24 13:40:35 +01:00
Juergen Hoeller 2233ec04ff StandardMultipartFile.transferTo falls back to manual copy
Issue: SPR-15257
(cherry picked from commit b73153c)
2017-03-24 13:40:29 +01:00
Juergen Hoeller e9ff3bb4e3 DefaultResponseErrorHandler delegate methods declared as protected
Also revises copyToByteArray/String in FileCopyUtils/StreamUtils for lenient null handling.

Issue: SPR-15329
(cherry picked from commit ab7db41)
2017-03-24 13:40:19 +01:00
Juergen Hoeller 57c8c759ae Avoid pattern misdetection in Tomcat "war:" URL separator
Issue: SPR-15332
(cherry picked from commit 012c56a)
2017-03-24 13:39:42 +01:00
Juergen Hoeller cfd9b3461f Process NULLABLE column as integer instead of boolean
Issue: SPR-15333
(cherry picked from commit 79ea779)
2017-03-24 13:39:10 +01:00
Rossen Stoyanchev d3324c8d4f Trap exception from SockJS HeartbeatTask
Issue: SPR-15307
2017-03-16 18:02:44 -04:00
Rossen Stoyanchev ffe9bae138 Update Javadoc on exception resolvers in MVC config
Issue: SPR-15324
2017-03-07 20:51:22 -05:00
Juergen Hoeller 020e51cb96 Polishing
(cherry picked from commit 94a7624)
2017-03-07 16:04:46 +01:00
Juergen Hoeller a78066830b Retrieve newly created attribute from underlying request (marking it for update)
Issue: SPR-15300
(cherry picked from commit f30c498)
2017-03-07 16:04:39 +01:00
Juergen Hoeller 77c771e874 Lookup methods work on configuration classes as well
Issue: SPR-15316
(cherry picked from commit fc2e635)
2017-03-07 16:04:16 +01:00
Juergen Hoeller 227ac3faa4 Explicit notes on transaction phase processing
Issue: SPR-15323
(cherry picked from commit 8b74150)
2017-03-07 16:04:09 +01:00
Juergen Hoeller 98dbc17591 Polishing 2017-03-07 10:33:48 +01:00
Juergen Hoeller e58b17a3a1 Adapt to JRuby 9.1.7+ RubyException.getMessage() method at runtime
Issue: SPR-15322
2017-03-07 10:33:34 +01:00
Juergen Hoeller 9de97614a0 Adapt to HtmlUnit 2.25 getCharset() return type at runtime
Issue: SPR-15319
2017-03-07 10:33:26 +01:00
Juergen Hoeller 015e00b5dd Upgrade to CGLIB 3.2.5
Includes Jetty 9.4.2, Netty 4.1.8, Commons I/O 1.4 as well.

Issue: SPR-15147
(cherry picked from commit 0d7b25f)
2017-03-07 10:23:57 +01:00
Stephane Nicoll 0bc59225d8 Polish contribution
Closes gh-1349
2017-03-05 09:35:09 +01:00
Aviskar Basnet d8acc27afb Polish doc
See gh-1349
2017-03-05 09:34:58 +01:00
Stephane Nicoll a1e4afe338 Update copyright header
Closes gh-1343
2017-03-03 09:35:29 +01:00
nkjackzhang 3b9faee335 Remove unecessary "<<"
See gh-1343
2017-03-03 09:35:16 +01:00
Spring Buildmaster 0048ff84ea Next Development Version 2017-03-01 08:53:20 +00:00
Juergen Hoeller c3f131325d Upgrade to Groovy 2.4.9 2017-02-28 14:01:09 +01:00
Juergen Hoeller b945e0f202 Polishing
(cherry picked from commit 6d6cf01)
2017-02-28 14:00:59 +01:00
Juergen Hoeller ce3cf3251d Tests for annotation lookups in interfaces (currently ignored for CGLIB proxies)
Issue: SPR-15271
Issue: SPR-14949
Issue: SPR-14322
(cherry picked from commit d003f66)
2017-02-28 14:00:39 +01:00
Juergen Hoeller d69fb06852 Skip transaction/caching metadata retrieval for java.lang.Object methods
Also retrieves CacheConfig as merged annotation now, aligned with other caching annotations.

Issue: SPR-15296
(cherry picked from commit d4a1b59)
2017-02-28 14:00:33 +01:00
Rossen Stoyanchev e9de3bb85b Fix wrong access modifier in MockMvc standalone setup
Issue: SPR-15248
2017-02-23 16:12:14 -05:00
Juergen Hoeller e6a51e3d29 Upgrade to Jackson 2.8.7 2017-02-22 16:32:51 +01:00
Juergen Hoeller c734c3a3fe Polishing 2017-02-22 16:32:21 +01:00
Juergen Hoeller a48a956c0c ConfigurationClassEnhancer explicitly handles non-interceptable FactoryBeans
Issue: SPR-15275
(cherry picked from commit 7fb0ad3)
2017-02-22 16:31:48 +01:00
Juergen Hoeller e5010a823b Test for expected behavior of getAllMergedAnnotations vs findAllMergedAnnotations
Issue: SPR-15271
(cherry picked from commit 6108ab1)
2017-02-22 16:31:40 +01:00
stonio 1db42081e5 Use String#isEmpty()
Closes gh-1335
(cherry picked from commit 7d062df)
2017-02-22 16:31:35 +01:00
Juergen Hoeller 34a0857628 Polishing
(cherry picked from commit d2cc97a)
2017-02-21 23:03:16 +01:00
Rossen Stoyanchev ba0484fcac Add equals/hashcode for STOMP Subscription
Issue: SPR-15229
2017-02-21 15:10:27 -05:00
Juergen Hoeller f1133a8e56 Upgrade to Hibernate ORM 5.2.8 2017-02-20 23:15:41 +01:00
Juergen Hoeller 35e37f6b60 Polishing 2017-02-20 23:15:05 +01:00
Juergen Hoeller f117b804a8 ServletRequestMethodArgumentResolver passes null references through (again)
Issue: SPR-15214
(cherry picked from commit fc11321)
2017-02-20 23:14:54 +01:00
Stephane Nicoll 278199d467 Revert "Improve allowNullValue handling when a null value is provided"
This reverts commit fd568f3e96.
2017-02-20 16:36:23 +01:00
Stephane Nicoll fd568f3e96 Improve allowNullValue handling when a null value is provided
This commit improves `AbstractValueAdaptingCache` to throw a dedicated
exception if `allowNullValues` is `false` and a `null` value is provided
anyway. This avoid a lower-level exception from the cache library that
will miss some context.

Issue: SPR-15173
2017-02-20 16:24:34 +01:00
Brian Clozel 45b27a85f4 Ignore HEAD requests in ShallowEtagHeaderFilter
Prior to this commit, the `ShallowEtagHeaderFilter` could participate in
the response and set its ETag/Content-Length headers, even for HEAD
requests. Since the response body is empty, the filter implementation
would set a `"Content-Length: 0"`.

The RFC states that responses to HEAD requests should exhibit identical
response headers to GET (with the possible exception of payload related
headers such as Content-Length.

With this commit, `ShallowEtagHeaderFilter` now ignores HEAD requests
since the proper values may be set already for payload related headers
by the handler. The filter has no way to generate a proper ETag value
nor calculate the content length without the actual body.

Issue: SPR-15261
(cherry picked from commit b732251)
2017-02-20 12:23:06 +01:00
Juergen Hoeller 0f71f58616 Polishing 2017-02-18 00:52:12 +01:00
Juergen Hoeller 9834c42b5c MutableMessageHeaders serializes itself as regular MessageHeaders
Issue: SPR-15262
(cherry picked from commit 74bdcd8)
2017-02-18 00:51:02 +01:00
Andy Clement 7879bdfc1d Fix compilation of SpEL elvis/ternary expressions
Without this fix the compiled version of elvis
actual behaved differently to the interpreted version
if the value being queried was an empty string. This
is now fixed. It also now correctly handles the
query value being a primitive and addresses the
findings of SPR-15192 where some type inferencing
logic was trying to be too clever, that code has
been deleted.

Issue: SPR-15192
(cherry picked from commit d41d28f)
2017-02-18 00:50:30 +01:00
Juergen Hoeller dfa8a7c358 Polishing 2017-02-16 15:57:52 +01:00
Juergen Hoeller 427fd9b19a OracleTableMetaDataProvider tries Connection.unwrap as well
Issue: SPR-14670
2017-02-16 15:57:39 +01:00
Juergen Hoeller 6417ed47ab Latest dependency updates (Apache HttpAsyncClient 4.1.3, BeanShell 2.0b5) 2017-02-16 14:20:54 +01:00
Juergen Hoeller b0ef80c3ff Polishing 2017-02-16 14:20:40 +01:00
Juergen Hoeller 7ed4884eaa Recent dialects for MySQL and SQL Server (as far as possible in 4.3.x)
Issue: SPR-15255
2017-02-16 14:20:33 +01:00
Juergen Hoeller c3cc42d4d3 Avoid double encoding of URIs
Issue: SPR-15254
2017-02-16 14:20:15 +01:00
Juergen Hoeller 860e2bcc2d Revised isInstanceOf/isAssignable message concatenation
Issue: SPR-15196
(cherry picked from commit 22322fd)
2017-02-16 14:20:07 +01:00
Juergen Hoeller 06231721c3 Consistently support CompletionStage next to CompletableFuture
Issue: SPR-15258
(cherry picked from commit 50d93d3)
2017-02-16 14:20:02 +01:00
Juergen Hoeller 4d2360e5b5 Defensively ignore multipart parsing failure in case of error dispatch
Issue: SPR-15231
(cherry picked from commit d44325e)
2017-02-16 14:19:57 +01:00
Stephane Nicoll 4f52174674 Update copyright header
Closes gh-1327
2017-02-14 10:41:03 +01:00
hengyunabc 7d7c5c9d9c Fix typo
See gh-1327
2017-02-14 10:40:51 +01:00
Brian Clozel 08b9e7b83e Avoid duplicate Content-Length headers in Netty client
This commit checks that a "Content-Length" request header isn't already
present before adding one in `Netty4ClientHttpRequestFactory`.
`HttpMessageConverter` implementations can write that request header so
the Netty request factory should only write that value when the header
is missing.

If that header is not written (and since we're not dealing with
the HTTP exchange in a chunked-based fashion), the HTTP client might not
send the request body at all.

Issue: SPR-15241
2017-02-13 21:19:51 +01:00
Juergen Hoeller e24c530705 Upgrade to Undertow 1.3.27 2017-02-10 11:48:18 +01:00
Juergen Hoeller 5017c05c23 Polishing
(cherry picked from commit e9019cd)
2017-02-10 11:47:28 +01:00
Juergen Hoeller 6e93834e27 Correct explanation of example patterns
Issue: SPR-15240
(cherry picked from commit e1bb697)
2017-02-10 11:47:10 +01:00
Juergen Hoeller 5f90a7eee9 Delegate to common ClassUtils.getQualifiedName
Issue: SPR-15237
(cherry picked from commit 81aca78)
2017-02-10 11:47:00 +01:00
Juergen Hoeller eff285eb3b MockHttpServletRequest exposes "HTTP/1.1" as default protocol
Issue: SPR-15232
(cherry picked from commit ed85337)
2017-02-10 11:46:42 +01:00
Juergen Hoeller da7d79b3a1 Test for ObjectFactory injection at constructor level
Issue: SPR-15222
(cherry picked from commit 65d8d69)
2017-02-10 11:46:32 +01:00
Juergen Hoeller d6216fb74a Consistent logging in ignoreResourceNotFound scenarios
Issue: SPR-15218
(cherry picked from commit 448ea4c)
2017-02-10 11:46:24 +01:00
Juergen Hoeller 941f3e7166 Clear synchronization before triggering afterCompletion callbacks
Issue: SPR-15194
Issue: SPR-11590
(cherry picked from commit b630c9b)
2017-02-10 11:46:13 +01:00
Stephane Nicoll e80c251c7a Update copyright header 2017-02-09 16:07:14 +01:00
Masayasu Yamamoto 56abc4a429 Fix Javadoc in ContentResultMatchers
Closes gh-1322
2017-02-09 16:07:05 +01:00
Stephane Nicoll dde9e27630 Polish 2017-02-06 15:31:39 +01:00
Stephane Nicoll 15b174a522 Polish contribution
Closes gh-1292
Issue: SPR-15188
2017-02-06 15:31:31 +01:00
David Brimley 1fcb2608fb Honour ErrorHandler if Cache.put fails
This commit makes sure that the `ErrorHandler` is invoked if the cache
fails to put an element (be it in the main cache or the exception cache).

See gh-1292
Issue: SPR-15188
2017-02-06 15:31:18 +01:00
Juergen Hoeller c15d687bf0 Polishing
(cherry picked from commit acf511a)
2017-02-02 21:20:27 +01:00
Juergen Hoeller e038631a6d Support for read-only transactions through explicit SET TRANSACTION statement
Issue: SPR-15210
(cherry picked from commit 02195f5)
2017-02-02 21:20:17 +01:00
Juergen Hoeller d5daa8e3a7 Skip default Content-Length if Transfer-Encoding header has been set
Issue: SPR-15212
(cherry picked from commit 9b3131f)
2017-02-02 21:19:53 +01:00
Juergen Hoeller 6014ca9140 ServletRequestMethodArgumentResolver validates argument type match
Issue: SPR-15214
(cherry picked from commit e44533f)
2017-02-02 21:19:45 +01:00
Juergen Hoeller d4010573af MockHttpServletRequest returns empty BufferedReader in case of no content
Issue: SPR-15215
(cherry picked from commit 0da964f)
2017-02-02 21:16:44 +01:00
Juergen Hoeller e3cd5c8ef0 SettableListenableFuture centralizes state in ListenableFutureTask subclass
Issue: SPR-15216
(cherry picked from commit c9b99da)
2017-02-02 21:16:36 +01:00
Juergen Hoeller dec1c93b24 SettableListenableFuture consistently tracks cancellation state
Issue: SPR-15202
(cherry picked from commit 9666fcc)
2017-01-31 16:11:23 +01:00
Juergen Hoeller 3ef6697536 Refined assertion messages
Issue: SPR-15196
(cherry picked from commit 9b26fcd)
2017-01-31 16:07:09 +01:00
Juergen Hoeller 8207c53b9a Polishing 2017-01-31 11:36:52 +01:00
Juergen Hoeller e3be94c961 Add headers in InterceptingClientHttpRequest
This commit *adds* the "intercepted" headers to the ClientHttpRequest,
as opposed to replacing them, which is what happened before this commit.

Issue: SPR-15166
2017-01-31 11:32:21 +01:00
Juergen Hoeller b40f016de2 Latest dependency updates (OkHttp 3.6, Apache HttpClient 4.5.3) 2017-01-31 10:29:21 +01:00
Juergen Hoeller 28849e0987 Revisit Assert to avoid single-arg assert methods (with refined messages)
Issue: SPR-15196
(cherry picked from commit 1b2dc36)
2017-01-31 10:28:46 +01:00
Spring Buildmaster b386be1529 Next Development Version 2017-01-25 13:34:40 +00:00
Juergen Hoeller a98a61852f HandlerMethod pre-resolves parameter types at construction time
Issue: SPR-15186
(cherry picked from commit 8038fb9)
2017-01-25 11:12:27 +01:00
Juergen Hoeller 3304efd64d Consistent type variable resolution for arrays/collections (in particular at field level)
Deprecating GenericCollectionTypeResolver in favor of direct ResolvableType usage.

Issue: SPR-15160
(cherry picked from commit 5e946c2)
2017-01-24 19:31:41 +01:00
Juergen Hoeller b97e7d53bc Revised CookieLocaleResolver parse exception handling
Issue: SPR-15182
(cherry picked from commit e8776f8)
2017-01-24 19:28:47 +01:00
Juergen Hoeller 4af6d58d8d Upgrade to Objenesis 2.5.1
Includes Hibernate ORM 5.2.7, Rome 1.7.1, Jetty 9.4.1, Undertow 1.3.26

Issue: SPR-15146
2017-01-23 23:47:22 +01:00
Juergen Hoeller e2d06eaae5 Deprecate outdated abstractions/delegates in core/util
Issue: SPR-15159
2017-01-23 23:47:14 +01:00
Juergen Hoeller fcfacd9f83 Polishing
(cherry picked from commit f095aa2)
2017-01-23 23:47:01 +01:00
Juergen Hoeller bddcc669b3 WebSocketSession.getExtensions consistently exposes unmodifiable/empty list
Issue: SPR-15180
(cherry picked from commit e94fa3f)
2017-01-23 23:33:04 +01:00
Juergen Hoeller 2024b37e65 HiddenHttpMethodFilter defensively proceeds with original request in case of error dispatch
Issue: SPR-15179
(cherry picked from commit a0df36d)
2017-01-23 23:32:20 +01:00
Juergen Hoeller fb3191904a DispatcherServet.checkMultipart considers MultipartException cause as well
Issue: SPR-15178
(cherry picked from commit ecc22f7)
2017-01-23 23:31:55 +01:00
Juergen Hoeller 9e4d74c502 Consider abstract classes with @Lookup methods as candidate components
Issue: SPR-14550
(cherry picked from commit 7d3fcaa)
2017-01-23 23:31:31 +01:00
Juergen Hoeller 9b221f58b9 Document further configuration class restrictions
Issue: SPR-14602
(cherry picked from commit 6fe7e56)
2017-01-23 23:31:03 +01:00
Juergen Hoeller f7c3b814e3 Only expose ASM-driven method order if the methods match
Issue: SPR-14505
(cherry picked from commit 253060c)
2017-01-23 23:30:36 +01:00
Juergen Hoeller 155bbb8466 Clear nonAnnotatedClasses cache in afterSingletonsInstantiated
Issue: SPR-15175
(cherry picked from commit e566e25)
2017-01-23 23:30:13 +01:00
Juergen Hoeller 4f690eea2a Drop classes folder (accidentally added in 35b67a5) 2017-01-23 22:37:39 +01:00
Rossen Stoyanchev 70a1ecba7f Documentation update related to Reactor version
Issue: SPR-15129
2017-01-23 15:02:01 -05:00
Rossen Stoyanchev c8b0ff2fca Add ExpectedCount#never()
Issue: SPR-15168
2017-01-20 17:11:09 -05:00
Stephane Nicoll f9a4856c3b Backport log4j doc improvements
Issue: SPR-15170
2017-01-20 17:38:20 +01:00
Brian Clozel 35b67a54d2 Upgrade to Tomcat 8.5.11 2017-01-20 09:55:33 +01:00
Rossen Stoyanchev 78a23be9bc Polish Reactor2TcpStompClient 2017-01-18 11:46:36 -05:00
Juergen Hoeller 09c5958608 Polishing 2017-01-18 00:53:59 +01:00
Juergen Hoeller ffb295971a Polishing 2017-01-18 00:27:04 +01:00
Rossen Stoyanchev 77bb7e6030 Add accessor methods to HttpPutFormContentFilter
Issue: SPR-14503
2017-01-17 17:18:03 -05:00
Rossen Stoyanchev 75daf781c2 Well-known names for beans in message broker XML config
Issue: SPR-15068
2017-01-17 17:08:45 -05:00
Rossen Stoyanchev fcead670f0 Add locking to AbstractRequestExpectationManager
This commit ensures that verifying a request, which includes finding
and updating expectations, is done synchronously to avoid concurrent
modification exceptions.

Technically SimpleRequestExpectationManager is not even expected to see
concurrent requests by definition but with
UnorderedRequestExpectationManager it can happen.

Issue: SPR-15029
2017-01-17 16:48:26 -05:00
Juergen Hoeller 801b93a078 Clarify WebContentInterceptor path mappings and efficiently match them
Issue: SPR-15096
2017-01-17 21:12:54 +01:00
Juergen Hoeller 4beeeb8118 ContentCachingRequestWrapper supports content cache limit
Issue: SPR-14829
(cherry picked from commit ad53867)
2017-01-17 20:57:28 +01:00
Juergen Hoeller 64d4afad9f SimpleApplicationEventMulticaster defensively swallows ClassCastException without message
Issue: SPR-15145
(cherry picked from commit 976d32f)
2017-01-17 20:43:59 +01:00
Rossen Stoyanchev 48f57e3bb2 Explicitly manage event loop in Reactor2TcpStompClient
Reactor2TcpStompClient now explicitly manages a Netty EventLoopGroup
which prevents resource leaks on attempts to reconnect.

Issue: SPR-15035
2017-01-17 14:19:36 -05:00
Juergen Hoeller d92f69747b Remove outdated groovy-bean-definition-dsl id in whats-new
Issue: SPR-15153
2017-01-17 16:23:55 +01:00
Juergen Hoeller 315698b50e Clarified cookieMaxAge default
Issue: SPR-15155
(cherry picked from commit 874b653)
2017-01-17 15:36:33 +01:00
Juergen Hoeller 6deccf123d Reference documentation for Groovy bean definition DSL
Issue: SPR-15153
(cherry picked from commit 2047f8d)
2017-01-17 15:35:24 +01:00
Juergen Hoeller 391ebc8eda Correct reference to XJC classpath
(cherry picked from commit 54da4a8)
2017-01-17 15:35:03 +01:00
Brian Clozel 28c7f65a25 Add SNI support in Netty4ClientHttpRequestFactory
This commit changes the `Bootstrap` to create a SSL Handler with
advisory peer information; this enables support for SNI.

Issue: SPR-15101
(cherry picked from commit 0c99346)
2017-01-17 11:32:10 +01:00
Juergen Hoeller caebe72083 Proper resolution of Optional.empty() for header arguments
Issue: SPR-15151
(cherry picked from commit e9db4d6)
2017-01-17 11:04:43 +01:00
Juergen Hoeller f79baec5ff Polishing
(cherry picked from commit 46fc7fb)
2017-01-16 23:14:12 +01:00
Vedran Pavić d1c0ea7d74 Set MockSessionCookieConfig#maxAge default to -1
Issue: SPR-15142
(cherry picked from 83beb9d57d)
2017-01-16 23:07:26 +01:00
Juergen Hoeller 53e2d7d160 Upgrade to Objenesis 2.5
(plus Groovy 2.4.8, Jackson 2.8.6, Netty 4.1.7)

Issue: SPR-15146
2017-01-16 22:44:07 +01:00
Juergen Hoeller 8c62a2f11a Polishing
(cherry picked from commit 95330d0)
2017-01-16 22:43:54 +01:00
Juergen Hoeller 8656e30550 Revised InvocableHandlerMethod exception messages (controller vs endpoint vs handler)
Introduces dedicated MethodArgumentResolutionException for spring-messaging invocations.

Issue: SPR-15139
(cherry picked from commit 047786a)
2017-01-16 22:43:48 +01:00
Juergen Hoeller 0655d73f8e SimpleApplicationEventMulticaster defensively handles ClassCastException without message
Issue: SPR-15145
(cherry picked from commit 153fd82)
2017-01-16 22:43:35 +01:00
Juergen Hoeller 24ebd15f9c Introspect FactoryBean class declaration if no early instantiation possible
Issue: SPR-15125
(cherry picked from commit 32fc855)
2017-01-16 22:43:18 +01:00
Juergen Hoeller cce84711c6 MockHttpServletRequestBuilder reliably detects form body content type again
Issue: SPR-15116
(cherry picked from commit e88e8f1)
2017-01-16 22:43:01 +01:00
Juergen Hoeller 7f127300f9 Polishing 2017-01-12 23:43:27 +01:00
Juergen Hoeller 1521094c5b MimeTypeUtils constants cleanup: deprecated web media types
Issue: SPR-15137
2017-01-12 23:43:00 +01:00
Juergen Hoeller 0b8134049c Upgrade to Joda-Time 2.9.7 2017-01-12 22:55:23 +01:00
Juergen Hoeller 70a980db58 Polishing 2017-01-12 22:54:23 +01:00
Juergen Hoeller 8b960099f1 Introduce media types for application/rss+xml
Issue: SPR-15109
2017-01-12 22:53:38 +01:00
Juergen Hoeller cc53d597c0 MySQLMaxValueIncrementer supports "useNewConnection" mode for INNODB tables
Issue: SPR-15107
2017-01-12 22:53:10 +01:00
Juergen Hoeller 5982f732b4 Improve performance of StringUtils.capitalize()
Issue: SPR-15094
2017-01-12 22:51:56 +01:00
Juergen Hoeller c5500b2332 MockHttpServletRequestBuilder supports multiple locales
Includes revised content type handling.

Issue: SPR-15116
(cherry picked from commit 02d727f)
2017-01-12 22:50:50 +01:00
Juergen Hoeller de611cb3a9 SpringValidatorAdapter properly handles HV-5-style list constraint violations
Issue: SPR-15082
(cherry picked from commit d0e9328)
2017-01-12 22:50:33 +01:00
Juergen Hoeller 72a76367f2 AbstractMessageSource does not attempt to format code-as-default-message
Issue: SPR-15123
(cherry picked from commit b06423a)
2017-01-12 22:50:22 +01:00
Juergen Hoeller 5afc3a3a50 Map resolution for multiple beans applies to plain Map interface declaration only
Issue: SPR-15117
(cherry picked from commit 8084da5)
2017-01-12 22:50:04 +01:00
Juergen Hoeller 2f2ef00d1f BeanDefinitionBuilder supports factory method on factory bean
Issue: SPR-15098
(cherry picked from commit 9e6aa0f)
2017-01-12 22:49:44 +01:00
Juergen Hoeller de7eea4498 GenericTableMetaDataProvider falls back to single schema as default
Issue: SPR-15090
(cherry picked from commit de43497)
2017-01-12 22:49:32 +01:00
Juergen Hoeller e9a87de965 LinkedCaseInsensitiveMap provides case-insensitive keySet again
Issue: SPR-15026
(cherry picked from commit 50e5a65)
2017-01-12 22:49:25 +01:00
Gary Russell db7b74feac Implement MessagingException.toString()
Issue: SPR-15091
Closes gh-1284
2017-01-05 10:25:55 +01:00
Philippe Marschall f7d126043b Remove use of Boolean constructors
Codacy warns us that there are several references to Boolean
constructors in the tests. Direct usage of the Boolean constructor is
discouraged and even deprecated in Java 9 [1]. Boolean constructor use
can easily be replaced with the constant instances.

This commit contains the following changes:

 - replace references to Boolean constructors with boolean constants in
   JSP tag tests
 - update the copyright year where necessary
 - BooleanComparatorTests is intentionally left unchanged as it should
   also work with the non-constant instances correctly

 [1] http://download.java.net/java/jdk9/docs/api/java/lang/Boolean.html#Boolean-boolean-

Issue: SPR-15076
2017-01-04 09:32:32 +01:00
Philippe Marschall 55b44b4f86 Avoid use of double constructor of BigDecimal
Codacy warns about an Error Prone [1] use of the double constructor of
BigDecimal in tests. The reason given is that it is a source of
precision loss if the number does not have an exact double
representation. The recommendation is to use the String constructor of
BigDecimal instead as it does not require using a lossy argument.

This commit contains the following changes:

 - replace usage of the double constructor of BigDecimal with the
   String constructor of BigDecimal in JdbcTemplateQueryTests
 - update the copyright year

 [1] http://errorprone.info/bugpattern/BigDecimalLiteralDouble

Issue: SPR-15077
2017-01-04 09:32:23 +01:00
Rob Winch 523370b6f2 Fix ForwardedHeaderFilter with non-empty contextPath
Issue: SPR-15088
2017-01-03 14:52:50 -06:00
Philippe Marschall 131d2c2051 Remove String#toCharArray from ScriptUtils
ScriptUtils contains two calls to String#toCharArray for the sole
purpose to iterating over all chars in a String. Not only is this
unnecessary and can be replaced with String#charAt it also causes
additional allocator and heap pressure because String#toCharArray
rather than returning the backing array (which is gone in Java 9)
creates a copy.

This commit contains the following changes:

 - remove String#toCharArray from ScriptUtils and replace with
   String#charAt

Issue: SPR-15075
2017-01-03 18:02:45 +01:00
Brian Clozel 7f05c2a18c Fix default content-type for ResourceRegion HTTP responses
Prior to this commit, the `ResourceRegionHttpMessageConverter` would
rely on the default implementation of `getDefaultContentType` to guess
the default Content-Type of the resource region to be written to the
HTTP response. That implementation fetches the first media type
provided in the HTTP request "Accept" header.

This behavior is not correct when converting resources and this commits
aligns this converter with the `ResourceHttpMessageConverter` which uses
JAF to guess the correct Content-Type of the given resource, or just
returns "application/octet-stream" as a default value.

Issue: SPR-15041
2017-01-03 11:18:40 +01:00
Juergen Hoeller 8fc65ab0a5 Clarified setAutowireCandidate semantics (plus attribute reordering in BeanDefinition)
Issue: SPR-15072
(cherry picked from commit e8a082f)
2016-12-30 11:55:55 +01:00
Juergen Hoeller b6108e3b2d Upgrade to ASM 5.2
Issue: SPR-15071
(cherry picked from commit ccabff6)
2016-12-30 11:55:50 +01:00
Juergen Hoeller 26a4aef417 Polishing
(cherry picked from commit fc629bb)
2016-12-29 23:12:11 +01:00
Juergen Hoeller 050f2c746d Track bean dependencies for calls between @Bean methods within @Configuration classes
Issue: SPR-15069
(cherry picked from commit a5c6658)
2016-12-29 23:12:05 +01:00
Juergen Hoeller fd21e0e69a @Scheduled reliably applies after other post-processors and shuts down before TaskScheduler
Issue: SPR-14692
Issue: SPR-15067
(cherry picked from commit edc62be)
2016-12-29 23:12:00 +01:00
Juergen Hoeller 794580ffcd TypeDescriptor efficiently matches equal annotations as well
Issue: SPR-15060
(cherry picked from commit e38c020)
2016-12-28 23:21:14 +01:00
Juergen Hoeller d44bc27c9a Avoid FactoryBean initialization on isSingleton check for decorated bean definition
Issue: SPR-14892
Issue: SPR-15042
(cherry picked from commit 209e7a7)
2016-12-28 23:20:15 +01:00
Juergen Hoeller 243e21a3ea Backport streamlined ClassPathBeanDefinitionScanner setup
Issue: SPR-15061
2016-12-27 18:32:03 +01:00
Juergen Hoeller 20aaa8841c PATCH does not work with the standard JDK HTTP library
Issue: SPR-15052
(cherry picked from commit 0480981)
2016-12-27 18:31:14 +01:00
Juergen Hoeller d77ab67c56 AbstractNestablePropertyAccessor's setPropertyValue refactored into several delegate methods
Issue: SPR-15053
(cherry picked from commit 64d6561)
2016-12-27 18:31:05 +01:00
Sebastien Deleuze dd2b6a0fc5 Avoid NPE in AutoProxyRegistrar when no attribute found
Issue: SPR-15055
2016-12-27 16:34:29 +01:00
Juergen Hoeller f949461297 Polishing
(cherry picked from commit a8741dd)
2016-12-26 11:40:49 +01:00
Juergen Hoeller 9a39a25bb5 Detect generic type match behind interface-based proxy as well
Issue: SPR-14097
(cherry picked from commit f805427)
2016-12-26 11:40:40 +01:00
Juergen Hoeller 4b018407c1 Expose reflection metadata with ASM-driven method order
Issue: SPR-14505
(cherry picked from commit 0208198)
2016-12-26 11:40:33 +01:00
Juergen Hoeller 28e114b569 Clarify programmatic contract (no annotation-driven injection)
Issue: SPR-8704
(cherry picked from commit fd41f63)
2016-12-26 11:40:25 +01:00
Juergen Hoeller 99226e0fa6 Polishing 2016-12-23 21:16:43 +01:00
Juergen Hoeller 4a84ee07be ConfigurationClassParser enforces @Bean declaration order through ASM metadata
Issue: SPR-14505
(cherry picked from commit 3295a4e)
2016-12-23 20:46:11 +01:00
Juergen Hoeller 505480cf63 LinkedCaseInsensitiveMap delegates to LinkedHashMap instead of extending it
Issue: SPR-15026
(cherry picked from commit 8147c11)
2016-12-23 20:46:07 +01:00
Juergen Hoeller fa2bfdd326 Remove unused Log object from MessageHeaderAccessor
Issue: SPR-15045
(cherry picked from commit 5c48daa)
2016-12-22 23:44:34 +01:00
Juergen Hoeller afe022853c Reintroduced initDefaultStrategies callback for compatibility with old MessageListenerAdapter subclasses
Issue: SPR-15043
2016-12-22 22:17:01 +01:00
Juergen Hoeller 41b834f76e Consistent ClassLoader propagation and ConcurrentHashMap setup for AspectJ pointcuts
Issue: SPR-15040
(cherry picked from commit d64d9ab)
2016-12-22 22:16:54 +01:00
Spring Buildmaster a88436c806 Next Development Version 2016-12-21 11:11:53 +00:00
Brian Clozel e2d6e709c3 Normalize resource URL in ResourceServlet
Issue: SPR-14946
2016-12-21 10:21:28 +01:00
Juergen Hoeller bd7fee5a77 Upgrade to Hibernate ORM 5.2.6 2016-12-21 10:10:49 +01:00
Juergen Hoeller 709d4ba6e7 Avoid explicit DecoratedObjectFactory setup in JettyRequestUpgradeStrategy
Issue: SPR-14940
2016-12-21 09:47:29 +01:00
Juergen Hoeller 8d55c7d60a Backported DataBinder configuration tests
Issue: SPR-15009
2016-12-21 09:31:55 +01:00
Juergen Hoeller 9cb4de8b5e Polishing 2016-12-20 21:11:07 +01:00
Juergen Hoeller 8662c61a17 Polishing
(cherry picked from commit 154ef8b)
2016-12-20 20:14:25 +01:00
Juergen Hoeller 935671ae32 Defensively catch any exception from match attempts (for compatibility with AspectJ 1.8.10)
Issue: SPR-15019
(cherry picked from commit 97ea22c)
2016-12-20 12:25:30 +01:00
Juergen Hoeller a5ce965d22 ConfigurationClassPostProcessor programmatically registers unified ImportAwareBeanPostProcessor
Issue: SPR-14931
(cherry picked from commit f6b2a21)
2016-12-20 12:25:22 +01:00
Juergen Hoeller 1e58c80fe7 MBeanExporter silently ignores null beans
Issue: SPR-15031
(cherry picked from commit 9c55d22)
2016-12-19 16:57:48 +01:00
Juergen Hoeller a92ae4ba30 Fixed backport gaps 2016-12-19 02:09:05 +01:00
Juergen Hoeller b5f2e56e38 Polishing 2016-12-19 01:51:57 +01:00
Juergen Hoeller 594f4d56b8 RestTemplate provides patchForObject operations
Issue: SPR-14857
2016-12-19 01:51:47 +01:00
Juergen Hoeller 2d83ca61e7 JdbcTemplate consistently delegates to getColumnMapRowMapper
Issue: SPR-15018
2016-12-19 01:49:58 +01:00
Juergen Hoeller 307e37a69f Flexible setMessageCodesResolver and deprecated setExtractOldValueForEditor at DataBinder level
Issue: SPR-15009
2016-12-19 01:49:38 +01:00
Juergen Hoeller 8310eb3b1f Latest dependency updates (OkHttp 3.5, Jackson 2.8.5, Jetty 9.3.14, Tomcat 8.5.9) 2016-12-19 01:49:12 +01:00
Juergen Hoeller b9c4f1fa95 ResolvableType-based matching respects generic factory method return type
Includes consistent use of ResolvableType.resolve() wherever applicable.

Issue: SPR-15011
(cherry picked from commit 4c005e6)
2016-12-19 01:12:14 +01:00
Juergen Hoeller faab4f9e28 Consistent DeferredResultHandler invocation outside of result lock
Issue: SPR-14978
(cherry picked from commit 37c734e)
2016-12-19 01:10:38 +01:00
Juergen Hoeller 271b0abc45 LocaleContextHolder provides support for framework-level default settings
Issue: SPR-15017
(cherry picked from commit 23f0418)
2016-12-19 01:10:09 +01:00
Juergen Hoeller f0c3d50408 Defensively catch IllegalStateException from match attempts (for compatibility with AspectJ 1.8.10)
Issue: SPR-15019
(cherry picked from commit 3370f41)
2016-12-19 01:09:36 +01:00
Juergen Hoeller f0fdff1f07 OkHttpClientHttpRequestFactory allows POST request without body
Issue: SPR-15015
(cherry picked from commit 2954385)
2016-12-19 01:09:06 +01:00
Juergen Hoeller d15df3489e Avoid proxy replacement for generic return type signatures
Issue: SPR-15010
(cherry picked from commit 6d1cae2)
2016-12-19 01:04:00 +01:00
Juergen Hoeller f3cc4ab09d @RequestBody supports java.util.Optional
Issue: SPR-15007
(cherry picked from commit eeb7ae5)
2016-12-19 01:03:18 +01:00
Juergen Hoeller 442d8a68a6 TypeDescriptor properly narrows ResolvableType for non-typed collection elements
Issue: SPR-14971
(cherry picked from commit aef1460)
2016-12-19 01:02:18 +01:00
Juergen Hoeller 934fffec68 AutowiredAnnotationBeanPostProcessor tolerates annotated no-arg constructors
Issue: SPR-15005
(cherry picked from commit 8b5ee4e)
2016-12-19 01:01:59 +01:00
Juergen Hoeller 8190e7838f SQLErrorCodesFactory provides unregisterDatabase method
This commit also migrates from a WeakHashMap to a ConcurrentReferenceHashMap, allowing for concurrent access to existing cache entries.

Issue: SPR-15006
(cherry picked from commit b825528)
2016-12-19 01:01:41 +01:00
Juergen Hoeller 4571975414 Collection injection may refer back to factory methods on same bean again
Issue: SPR-14996
(cherry picked from commit 547b963)
2016-12-19 01:01:16 +01:00
Juergen Hoeller 5115c61b03 CommonsMultipartFile.getOriginalFilename() can be configured to preserve header-specified filename as-is
Issue: SPR-14613
(cherry picked from commit aa29495)
2016-12-19 00:59:28 +01:00
Juergen Hoeller 54c7a9ee95 Revised Jetty 9.3 vs 9.4 differentiation
Issue: SPR-14940
(cherry picked from commit 52799c0)
2016-12-19 00:58:53 +01:00
Juergen Hoeller 0296c7c5b6 Stronger explanation of default rollback rules
Issue: SPR-14994
(cherry picked from commit 953bc18)
2016-12-19 00:58:44 +01:00
Juergen Hoeller 84d8135cbb MimeType parsing properly handles quoted semicolons
Issue:  SPR-14986
(cherry picked from commit 7714eec)
2016-12-19 00:58:23 +01:00
Juergen Hoeller dd3c370bca ImportRegistry properly tracks excluded superclasses
Issue: SPR-14972
(cherry picked from commit a7ec6dc)
2016-12-19 00:57:45 +01:00
Juergen Hoeller 4e41f74925 Explicit support for retrieving enum values
Issue: SPR-14990
(cherry picked from commit 278a625)
2016-12-19 00:56:44 +01:00
Juergen Hoeller c6663f59b8 HttpInvokerClientInterceptor propagates client-side Error as-is
Issue: SPR-14985
(cherry picked from commit ee30ce9)
2016-12-19 00:56:06 +01:00
Juergen Hoeller ced7503d95 Revised forClass argument names
Issue: SPR-14976
(cherry picked from commit 8ab977e)
2016-12-19 00:55:39 +01:00
Juergen Hoeller 04af30daed JPA/Hibernate docs: transaction management, JTA setup
Issue: SPR-14957
(cherry picked from commit 2f80b84)
2016-12-19 00:55:19 +01:00
Juergen Hoeller 5ccc8e341c SpEL docs: supported literals, null comparisons
Issue: SPR-14361
Issue: SPR-14987
(cherry picked from commit 05579fd)
2016-12-19 00:55:03 +01:00
Juergen Hoeller 71977e8f9d Consistent use of "URI variables" terminology
Issue: SPR-14969
(cherry picked from commit 6517c53)
2016-12-19 00:54:49 +01:00
Rob Winch 5e774e0b44 Add Support for ForwardedHeaderFilter sendRedirect
Previously ForwrdedHeaderFilter did not ensure that
HttpServletResponse.sendRedirect worked properly based on
X-Forwarded-* headers.

This commit updates ForwardedHeaderFilter to overrided the
HttpServletResponse.sendRedirect method to ensure
X-Forwarded-* headers are honored.

Issue SPR-15020
2016-12-15 19:38:40 -05:00
Rossen Stoyanchev e16d753439 Allow athentication at the STOMP level
This commit makes it possible for a ChannelInterceptor to override the
user header in a Spring Message that contains a STOMP CONNECT frame.

After the message is sent, the updated user header is observed and
saved to be associated with session thereafter.

Issue: SPR-14690
2016-12-13 16:17:05 -05:00
Rossen Stoyanchev b14d189db9 MockRestRequestMatchers can match query params
Issue: SPR-14995
2016-12-13 16:07:19 -05:00
Brian Clozel 14de29c031 Improve VersionResourceResolve javadoc
The `pathPatterns` args are relative to the patterns configured for the
resource handler.

Issue: SPR-14817
Cherry-picked from: 52f664139
2016-12-13 11:01:14 +01:00
Brian Clozel b59455b63c Do not include URL hash in resource paths
When getting the lookup path of a resource, both query params and hashes
should be removed from the request path.

This commit fixes the public path resolution for paths like
`/resources/main.svg#icon-hamburgermenu`.

Issue: SPR-14928
2016-12-12 15:23:23 +01:00
Brian Clozel 1a6dc86fed Allow RedirectAttributes on ExceptionHandlers
Prior to this commit, `@ExceptionHandler` methods could not be injected
with `RedirectAttributes` arguments. This would make it impossible to
handle an error by redirecting to another view and add flashmap
attributes, to be included in the model when the next view is called.

Here is an example:

```
@ExceptionHandler(MyException.class)
public String handleException(MyException ex, RedirectAttributes
    redirectAttributes) {

  redirectAttributes.addFlashAttribute("errorMessage",
      "This is an error message");
  return "redirect:/";
}
```

This commit adds a new `RedirectAttributesMethodArgumentResolver`
instance in the list of pre-configured `HandlerMethodArgumentResolver`
in `ExceptionHandlerExceptionResolver`.

Issue: SPR-14651
Cherry-picked from: 17089d6
2016-12-12 09:09:35 +01:00
Brian Clozel 35b0c8b577 Update websocket support for Jetty 9.3+
Due to a few changes in `WebSocketServerFactory` and `Session` API, our
`JettyRequestUpgradeStrategy` and `JettyWebSocketSession` needed to
adapt. As of 9.3.15+ and 9.4.0+, some reflection is required to support
previous versions.

Spring 4.3 websocket officially supports Jetty 9.1 to 9.3.

Issue: SPR-14940
2016-12-09 14:58:18 +01:00
Brian Clozel 75034c3710 Revert "Update websocket support for Jetty 9.3+"
This reverts commit 305cea28c5.
2016-12-08 22:48:06 +01:00
Brian Clozel 305cea28c5 Update websocket support for Jetty 9.3+
Due to a few changes in `WebSocketServerFactory` and `Session` API, our
`JettyRequestUpgradeStrategy` and `JettyWebSocketSession` needed to
adapt. As of 9.3.15+ and 9.4.0+, some reflection is required to support
previous versions.

Spring 4.3 officially supports Jetty 9.1 to 9.3.

Issue: SPR-14940
2016-12-08 21:44:31 +01:00
Rossen Stoyanchev 69ba85b051 Backport of STOMP message header encoding improvements
Issue: SPR-14901
2016-12-08 11:33:16 -05:00
Sebastien Deleuze 5700d65a53 Append "data:" after line breaks for SSE JSON data fields
Issue: SPR-14899
2016-12-08 14:16:41 +01:00
bedrin e707c40e0b Add consumes attribute to @GetMapping
Issue: SPR-14988
2016-12-07 17:51:05 -05:00
Brian Clozel 9d37472f23 Fix Netty4ClientHttpRequestFactory POST/PUT requests
This commit ensures that POST/PUT requests sent by the Netty client have
a Content-Length header set.

Integration tests have been refactored to use mockwebserver instead of
Jetty and have been parameterized to run on all available supported
clients.

Issue: SPR-14860
Cherry-picked from: ec8391a7fb
2016-12-07 09:24:13 +01:00
Juergen Hoeller eb97335c6f Polishing 2016-12-01 20:19:49 +01:00
Juergen Hoeller 0028b29760 Polishing 2016-12-01 19:09:26 +01:00
Juergen Hoeller 1ded1e38e8 Latest dependency updates (Caffeine 2.3.5, Hibernate ORM 5.2.5, Joda-Time 2.9.6, Tomcat 8.5.8, JOpt Simple 5.0.3) 2016-12-01 19:08:57 +01:00
Juergen Hoeller 149acdae7d @UsesJava8
Issue: SPR-14958
2016-12-01 14:23:59 +01:00
Juergen Hoeller 5fee5f39ea Polishing 2016-12-01 14:13:23 +01:00
Juergen Hoeller f16d453805 PathMatchingResourcePatternResolver converts manifest entries to absolute paths and tries all root URLs (any file extension) as jar file
Issue: SPR-14934
Issue: SPR-14936
2016-12-01 14:12:56 +01:00
Juergen Hoeller 2b0293578f Consistent use of "URI variables" terminology
Issue: SPR-14969
(cherry picked from commit 7a8ec4f)
2016-12-01 14:12:07 +01:00
Juergen Hoeller 66aeeedaef Test injection point match for narrow target return type
Issue: SPR-14960
(cherry picked from commit 845dbf0)
2016-12-01 14:12:00 +01:00
Juergen Hoeller af41dd1ed6 Efficient ISO_LOCAL_* variants for printing LocalDate/LocalTime/LocalDateTime
Issue: SPR-14958
(cherry picked from commit 1ae17c2)
2016-12-01 14:11:49 +01:00
Juergen Hoeller 17f7f1fc15 Consistent catching of Throwable for introspection failures
Issue: SPR-12889
(cherry picked from commit 0186809)
2016-12-01 14:11:43 +01:00
Juergen Hoeller cbc512f3be Efficient type plus annotation comparisons during converter retrieval
Issue: SPR-14926
Issue: SPR-12926
(cherry picked from commit f6b8b84)
2016-12-01 14:11:34 +01:00
Juergen Hoeller 7ac9f92bc2 Various DefaultListableBeanFactory clarifications
* getBeanDefinitionNames defensively returns a copy of the bean definition names array.
* copyConfigurationFrom provides an independent AutowireCandidateResolver instance and copies a ConversionService and dependency comparator configuration as well.
* findAutowireCandidates only considers a self reference fallback for direct dependency declarations, not as a collection element.

Issue: SPR-14897
Issue: SPR-14921
Issue: SPR-14965
(cherry picked from commit ac5933a)
2016-12-01 14:11:08 +01:00
Juergen Hoeller a7ba63d425 Shared DefaultConversionService instance for simple fallback purposes
Issue: SPR-14948
(cherry picked from commit 80931b2)
2016-12-01 14:10:39 +01:00
Juergen Hoeller 5ca10b1d67 Consistent ExpressionException-style quoting of expression string and position
Issue: SPR-14942
(cherry picked from commit 14eba50)
2016-12-01 14:10:23 +01:00
Juergen Hoeller f22a4a4e80 No warn logging for propagated original exception
Issue: SPR-14907
(cherry picked from commit 96bfc14)
2016-12-01 14:10:01 +01:00
Juergen Hoeller b53ee13662 JdbcUtils explicitly extracts SQL date/time for JSR-310 LocalDate/Time
Issue: SPR-14898
(cherry picked from commit a0fee46)
2016-12-01 14:09:53 +01:00
Christoph Dreis 8de100b116 Implement allocation-friendly method to get user count in SimpUserRegistry
SPR-14930
(cherry picked from commit a929e9c)
2016-12-01 14:09:43 +01:00
Juergen Hoeller ac30bcb0eb WebSocketServerSockJsSession uses dedicated disconnect lock
Issue: SPR-14917
(cherry picked from commit a49809b)
2016-12-01 14:09:34 +01:00
Rossen Stoyanchev 872d6ef55a HtmlUnitRequestBuilder detects form encoding type
Issue: SPR-14916
2016-11-28 18:08:44 -05:00
Rossen Stoyanchev dd3b9c7c35 ResponseEntity headers builder casts body to any type
Issue: SPR-14939
2016-11-28 17:25:20 -05:00
Rossen Stoyanchev 9755ae3cbe PayloadArgumentResolver has useDefaultResolution flag
Issue: SPR-14937
2016-11-28 17:02:03 -05:00
Brian Clozel bc29fb5a09 Do not execute ResourceUrlEncodingFilter only once per request
In case the filter is also registered to the ERROR dispatcher, the
following happens:
* the filter is executed once for the regular execution
* the filter should be executed a second time when dispatched to error

Since the filter is a `OncePerRequestFilter`, the filter is only
executed once and won't be executed when handling the error.

This can lead to situations like spring-projects/spring-boot#7348

This commit makes this filter a simple `GenericFilterBean`.

Issue: SPR-14891
2016-11-24 10:03:08 +01:00
Rossen Stoyanchev 646a574b9c Deprecate ResourceServlet 2016-11-23 21:22:58 -05:00
Rossen Stoyanchev 8f19650fd7 Avoid locking in WebSocket session "close" callback
When processing a "close" notification from the server make an effort
to cancel any outstanding heartbeat but avoid going as far as acquiring
the responseLock since the server itself may already hold a lock of its
own leading to a potential deadlock.

The heartbeat task is now also further protected with an isClosed()
check in case the heartbeat does not get cancelled in a concurrent
scenario.

Issue: SPR-14917
2016-11-23 20:58:22 -05:00
Stephane Nicoll f08980967b Polish doc 2016-11-17 07:25:42 +09:00
Mark Paluch 5285f5300a Fix TLS detection in URLs for Netty Client RequestFactory
Do not check on non-specified port when scheme is https.
Enables SSL for https URIs with a specified port.

Issue: SPR-14889
2016-11-11 16:49:18 +01:00
Juergen Hoeller 1608d0596d Polishing 2016-11-11 16:48:43 +01:00
Juergen Hoeller 62631bfe33 Detect invalid configuration for autoGrowCollectionLimit on DataBinder
Issue: SPR-14888
2016-11-08 17:47:29 +01:00
Juergen Hoeller 7ffed858f0 ASM-generated class names get interned for better memory allocation
Issue: SPR-14886
(cherry picked from commit 3a29daa)
2016-11-08 17:47:14 +01:00
Spring Buildmaster 3a1334e0d4 Next Development Version 2016-11-07 21:35:52 +00:00
Juergen Hoeller 37f4f43726 Consistent 4.x style NoClassDefFoundError handling
Issue: SPR-14883
2016-11-07 19:13:00 +01:00
Juergen Hoeller db1a84ede1 Polishing 2016-11-07 18:48:35 +01:00
Juergen Hoeller 3d2e4c338c Refined throwing of BeanCreationExceptions (and reflection exceptions)
Issue: SPR-14883
2016-11-07 18:47:54 +01:00
Juergen Hoeller b42d731fc8 Consistent throwing of BeanCreationExceptions (and reflection exceptions)
Issue: SPR-14883
2016-11-07 16:56:35 +01:00
Juergen Hoeller fd7045adac Polishing
(cherry picked from commit 9b57437)
2016-11-07 13:02:50 +01:00
Juergen Hoeller e26d3505f7 Upgrade to OkHttp 3.4.2 and Tiles 3.0.7 2016-11-04 14:55:37 +01:00
Juergen Hoeller fe0249bf8f Polishing 2016-11-04 13:37:06 +01:00
Juergen Hoeller 2ac682e125 Upgrade to Joda-Time 2.9.5 2016-11-04 13:30:25 +01:00
Juergen Hoeller 9be1710dca @Async docs explicitly mention ListenableFuture and CompletableFuture
Issue: SPR-14881
(cherry picked from commit 8df45dd)
2016-11-04 13:30:11 +01:00
Juergen Hoeller 7e7504f5ea Polishing 2016-11-03 23:20:33 +01:00
Juergen Hoeller e83c11667f ApplicationListenerDetector ignores non-managed bean instances
Issue: SPR-14879
(cherry picked from commit 8ae0bd6)
2016-11-03 23:20:06 +01:00
Juergen Hoeller 05547979de Polishing
Issue: SPR-14867
(cherry picked from commit a90e4b2)
2016-11-03 14:54:15 +01:00
Juergen Hoeller 9e67ba83a5 Consistent support for early placeholder resolution in properties locations
Issue: SPR-10502
(cherry picked from commit 8053fef)
2016-11-03 14:53:46 +01:00
Juergen Hoeller 2bb3522bbb ReloadableResourceBundleMessageSource sets file timestamp on merged holder
Issue: SPR-14583
(cherry picked from commit 03468fd)
2016-11-03 14:53:24 +01:00
Rossen Stoyanchev 8f4ec35697 Check SockJS session type
This commits adds a validation check whether the SockJS session type
matches the transport type and rejects requests for which they
don't match.

Issue: SPR-14867
2016-11-03 09:38:24 +02:00
Juergen Hoeller 17863dfbda AnnotatedElementAdapter explicitly declares isAnnotationPresent method
Issue: SPR-14872
2016-11-02 14:41:11 +01:00
Juergen Hoeller 56bb20d489 Upgrade to HtmlUnit 2.23 and JSONAssert 1.4 2016-11-02 14:40:10 +01:00
Juergen Hoeller 5baf32cd81 Upgrade to Caffeine 2.3.4 2016-11-02 14:02:49 +01:00
Andy Clement 38cd1ecff4 Rework compilation of OpNE/OpEQ SpEL operators
For SPR-14863 we need to adjust the code generation for OpNE
to use !x.equals(y) rather than x!=y. There are also further
cases in the equalityCheck() code in Operator that were not
being handled in the compilation case (when comparators are
used for example). This latter issue also affects OpEQ.

Rather than add yet more bytecode generation, both OpNE and
OpEQ generateCode() methods have been simplified. The
generated code now delegates to equalityCheck() in Operator
which is exactly what the interpreted case does.

This ensures that the compiled code continues to behave just
like the interpreted case. It ensures changes to the interpreted
case are automatically picked up for the compiled case. It
makes the bytecode generation simpler.

The benefit of compilation of SpEL expressions is to avoid
slow reflective calls - that doesn't apply for a basic
(in)equality test so there is no need to go crazy in bytecode
gen.

Issue: SPR-14863
(cherry picked from commit 9000acd)
2016-11-02 12:40:24 +01:00
Juergen Hoeller 77e00f1926 Polishing 2016-10-31 20:40:46 +01:00
Juergen Hoeller ade139f2d0 Polishing
(cherry picked from commit 45fc449)
2016-10-31 19:29:04 +01:00
Juergen Hoeller 653f35a3d8 Upgrade to H2 1.4.193 and Derby 10.13.1.1
(cherry picked from commit eaf8078)
2016-10-31 19:28:58 +01:00
Juergen Hoeller baa7aecf60 Polishing
(cherry picked from commit 7f280a3)
2016-10-31 12:40:44 +01:00
Juergen Hoeller d859826be6 ASM-generated class names get interned for better memory allocation
Issue: SPR-14862
2016-10-31 11:56:34 +01:00
Juergen Hoeller d759c96a98 Latest applicable dependency updates (Hibernate ORM 5.2.4, Gson 2.8, Guava 20) 2016-10-31 11:54:29 +01:00
Juergen Hoeller 7cbab0efe3 LocalSessionFactoryBean clears default MetadataSources on reinitialization
Issue: SPR-14815
2016-10-31 11:53:10 +01:00
Arjen Poutsma b6b536682e Make HttpComponentsAsyncClientHttpRequest abortable
This commit aborts the HttpComponentsAsyncClientHttpRequest whenever the
returned Future is canceled.

Issue: SPR-14845
(cherry picked from commit 8f84446)
2016-10-31 11:51:26 +01:00
Juergen Hoeller edf1df33cc ObjectToObjectConverter properly handles constructors on non-public classes
Issue: SPR-14304
(cherry picked from commit 9659bc5)
2016-10-31 11:51:05 +01:00
Juergen Hoeller bf0df54136 Consistent instanceof/casting of Class references
(cherry picked from commit ac80ac6)
2016-10-31 11:50:59 +01:00
Juergen Hoeller 7e80d2de79 Exceptions thrown from @ExceptionHandler methods logged at warn level (instead of debug)
Issue: SPR-14861
(cherry picked from commit 7627c38)
2016-10-31 11:50:45 +01:00
Juergen Hoeller 144f687ee9 Polishing
(cherry picked from commit 2f9ed59)
2016-10-31 11:50:36 +01:00
Juergen Hoeller 0ee8322947 Revised NoSuchBeanDefinitionException message and ResolvableType handling
Includes consistent quoting of qualified type names in related classes.

Issue: SPR-14831
(cherry picked from commit dc080cb)
2016-10-31 11:50:15 +01:00
Juergen Hoeller 997fb5fb48 DefaultListableBeanFactory allows early type matching against ScopedProxyFactoryBean
Issue: SPR-14816
(cherry picked from commit 3633244)
2016-10-31 11:50:02 +01:00
Juergen Hoeller 2b459881bd ApplicationListener detection for inner beans behind post-processors
Issue: SPR-14783
(cherry picked from commit c946924)
2016-10-31 11:49:06 +01:00
Juergen Hoeller e18e7eca47 No external locking for singleton advice/aspect beans
Issue: SPR-14324
(cherry picked from commit 5ac5ec1)
2016-10-31 11:48:12 +01:00
Juergen Hoeller 1c80d2ac2f Avoid deadlock between SockJS heartbeat and XHR polling
Issue: SPR-14833
(cherry picked from commit 72e1f7e)
2016-10-31 11:47:23 +01:00
Juergen Hoeller 62918ca779 TypeDescriptor supports merged annotation lookups (for composable formatting annotations)
Issue: SPR-14844
(cherry picked from commit bf9083d)
2016-10-31 11:46:30 +01:00
Juergen Hoeller 3cca57a801 Local merged annotation lookup in SpringCacheAnnotationParser
Issue: SPR-14781
Issue: SPR-14801
(cherry picked from commit 08972ef)
2016-10-31 11:45:35 +01:00
Juergen Hoeller 5578a2e46d Test for multi-character delimiter
Issue: SPR-14808
(cherry picked from commit 71d8338)
2016-10-31 11:45:01 +01:00
Juergen Hoeller fe19cfde28 Tightened StringValueResolver contract
Issue: SPR-14842
(cherry picked from commit 20419d7)
2016-10-31 11:44:46 +01:00
Juergen Hoeller fbad637235 SimpleApplicationEventMulticaster just swallows event downcast exceptions
Issue: SPR-14846
(cherry picked from commit 13001b9)
2016-10-31 11:44:26 +01:00
Juergen Hoeller 01e9307fb7 DataSourceTransactionManager triggers flush callbacks on registered transaction synchronizations
Issue: SPR-14847
(cherry picked from commit 2874066)
2016-10-31 11:44:17 +01:00
Juergen Hoeller 5697cb6c95 AccessorLValue reliably downcasts to CompilablePropertyAccessor in concurrent scenarios
Issue: SPR-14850
(cherry picked from commit e2b1dcb)
2016-10-31 11:44:08 +01:00
Juergen Hoeller 05ff83f95a ResourceHttpRequestHandler initializes PathExtensionContentNegotiationStrategy in afterPropertiesSet
Issue: SPR-14851
(cherry picked from commit b7d3a96)
2016-10-31 11:43:57 +01:00
Stephane Nicoll 1e3012cb49 Allow to customize TestDispatcherServlet
This commit introduces the `DispatcherServletCustomizer` callback
interface that can be used to customize the `DispatcherServlet` that a
`MockMvc` is using.

Previously, only the `dispatchOptions` flag can be customized. This
commit allows to customize any property of `DispatcherServlet` before it
is initialized.

Issue: SPR-14277
2016-10-29 11:09:48 +02:00
Rossen Stoyanchev 45b8cf350e Better handling for AsyncRequestTimeoutException
Avoid call to sendError when response is committed and log a short
error message instead.

Issue: SPR-14739
2016-10-28 17:41:48 +03:00
Stephane Nicoll 2c2c6f8e02 Fix broken build
This commit fixes the direct use of Java8 API

Issue: SPR-14853
2016-10-27 10:30:54 +02:00
Stephane Nicoll 4e3a6b9404 Polish 2016-10-27 10:01:51 +02:00
Stephane Nicoll 76bbccb4dc Allow @Cacheable method to return Optional
This commit further refines 240f254 to also support java.util.Optional
for synchronized cache access (i.e. when the `sync` attribute on
`@Cacheable` is set to `true`).

Issue: SPR-14853
2016-10-27 10:00:34 +02:00
Stephane Nicoll 1c4433555a Move NoOpCache to a top-level public class
This commit moves `NoOpCache` to a top-level public class to allow reuse
in custom CacheManager arrangement.

Issue: SPR-14856
2016-10-27 09:09:51 +02:00
Eric Jain faaced1d86 Escape (( and )) to prevent asciidoc processing
See http://asciidoctor.org/docs/user-manual/#user-index

Closes gh-1225
2016-10-27 08:50:27 +02:00
Stephane Nicoll 1a1d17e13a LiveBeansView does not rely on application contexts order anymore
This commit makes sure that the `unregister` order of registered
application contexts has no incidence on the removal of the LiveBeansView
MBean.

Rather than using the last application context's name to compute the
identity of the MBean to remove, the identity is stored when the MBean is
created.

This commit also adds missing tests.

Issue: SPR-14848
2016-10-26 15:03:44 +02:00
Stephane Nicoll 4254b6d0e2 Polish contribution
Closes gh-1203
2016-10-26 09:50:48 +02:00
Vitalii a211c2a955 Fix javadoc syntax
See gh-1203
2016-10-26 09:50:36 +02:00
Stephane Nicoll 196200bcc0 Clarify SpEL usage on @EventListener
Issue: SPR-14812
2016-10-25 17:45:36 +02:00
Rossen Stoyanchev c062835702 Respect ModelAndView.status in @ExceptionHandler
Issue: SPR-14006
2016-10-24 16:36:44 +01:00
Juergen Hoeller 664ef756c2 Latest dependency updates (EhCache 2.10.3, Jackson 2.8.4, Jetty 9.3.13, Netty 4.1.6) 2016-10-21 13:00:11 +02:00
Juergen Hoeller 9de28d640e Polishing
(cherry picked from commit 3726c6f)
2016-10-21 12:59:59 +02:00
Juergen Hoeller adb9dc7ede ResolvableType equals/hashCode does not consider TypeProvider source
Issue: SPR-14826
(cherry picked from commit be187ba)
2016-10-21 12:59:54 +02:00
Juergen Hoeller f9fcd24315 ConversionService detects generic type declaration on target class behind proxy as well
Issue: SPR-14822
(cherry picked from commit f7d740f)
2016-10-21 12:59:48 +02:00
Juergen Hoeller 6d95b999ad DefaultTransactionAttribute stores descriptor (method identification)
Issue: SPR-14760
(cherry picked from commit 52b029d)
2016-10-21 12:59:43 +02:00
Sebastien Deleuze 6731e52280 Better encapsulation for CORS default permit configuration
This commit also improves CorsRegistration Javadoc.

Issue: SPR-14798
2016-10-20 17:06:12 +02:00
Rossen Stoyanchev 970358b2af Relax generic type detection for ResponseEntity
Before this change the getHttpEntityType method in
HttpEntityMethodProcessor raised an ISE if the generic type cannot be
detected. That made sense for resolving a controller method argument
where the target body type is crucial. However for a return value
the generic type should not be required since we either have an
actual body or no body at all in which case it doesn't even matter.

This change relaxes the checks and defaults to Object.class for the
ResponseEntity generic type on the return value side.

Issue: SPR-14799
2016-10-13 13:59:13 -04:00
Juergen Hoeller 3d68950037 Upgrade to Tomcat 8.5.6 and JRuby 1.7.26 2016-10-12 17:52:36 +02:00
Juergen Hoeller d50b2a4804 Documentation for InjectionPoint argument on @Bean method
Issue:  SPR-14797
(cherry picked from commit 69116c2)
2016-10-12 17:48:50 +02:00
Juergen Hoeller 29a946163b Polishing
(cherry picked from commit eafaaa5)
2016-10-12 17:48:33 +02:00
Juergen Hoeller 9472025da7 BindingResult does not hold on to ConversionService when serialized in session
Issue: SPR-8282
(cherry picked from commit 74b6a5b)
2016-10-12 17:48:08 +02:00
Juergen Hoeller f5cd5387da StompSubProtocolHandler does not insist on SimpMessageHeaderAccessor
Issue: SPR-14791
(cherry picked from commit 66722af)
2016-10-12 17:47:58 +02:00
Stephane Nicoll 7a8bf8e9a5 Polish EnableAsync javadoc
Issue: SPR-14793
(cherry picked from commit ab232a5)
2016-10-12 17:47:28 +02:00
Sebastien Deleuze f5ecdda400 Remove duplicated elements in CorsConfiguration#combine()
Issue: SPR-14792
2016-10-11 10:53:33 +02:00
Sebastien Deleuze c2031aa651 Polish CorsConfigurationTests 2016-10-11 10:41:14 +02:00
Brian Clozel 8751c9931e Fix NumberFormatException with X-Forwarded-Host
This commit fixes `NumberFormatException`s that were thrown when parsing
IPv6 host values in `X-Forwarded-Host` request headers.

Issue: SPR-14761
(cherry picked from ea5ff87f8e)
2016-10-07 23:19:01 +02:00
Brian Clozel adbf9922f4 Configure default SSL context in Netty RequestFactory
This commit configures a default SslContext if none has been provided.
This also enforces separate Netty bootstrap instances for cleartext and
TLS exchanges.

Issue: SPR-14744
(cherry picked from 53441f8)
2016-10-06 16:50:27 +02:00
Stephane Nicoll b3a1e5f9e9 Fix table layout 2016-10-06 15:27:25 +02:00
Juergen Hoeller 22f70f9ac9 Upgrade to EhCache 3.1.3 and Hibernate ORM 5.2.3 2016-10-06 00:16:29 +02:00
Juergen Hoeller d2079f32d8 SpringValidatorAdapter declares ResolvableAttribute as serializable
Issue: SPR-14778
(cherry picked from commit ebed7b7)
2016-10-06 00:16:00 +02:00
Juergen Hoeller f2ac416f66 Consistent final logger fields
(cherry picked from commit cfa0f6c)
2016-10-06 00:15:45 +02:00
Juergen Hoeller 642fbfba9f @Lookup reference documentation
Issue: SPR-14765
(cherry picked from commit 684d6ab)
2016-10-06 00:15:38 +02:00
Brian Clozel c98cdd4f4c Fix missing ETag/LastModified headers in responses
Prior to this commit, the `HttpEntityMethodProcessor` would avoid
writing ETag/Last-Modified response headers before calling
`ServletWebRequest` to process conditional requests. This was done to
avoid duplicate response header values due to headers being already
written to the underlying servlet response.

This is still necessary for GET/HEAD requests, since this is properly
handled by `ServletWebRequest` for those cases. But
`HttpEntityMethodProcessor` should not make that decision for
PUT/PATCH/POST responses since developers are adding response headers on
purpose and should be in control of the situation — whereas
`ServletWebRequest` does not write those headers in those cases.

Issue: SPR-14767
Cherry-picked from: ee17f5662
2016-10-04 13:54:02 +02:00
Juergen Hoeller d04567b99c Polishing 2016-09-26 18:19:04 +02:00
Juergen Hoeller f2e1e1b890 Efficient STOMP content-length header check
Issue: SPR-14747
(cherry picked from commit a6b0b6e)
2016-09-26 17:30:45 +02:00
Juergen Hoeller 6c764f6b8a StompEncoder performance improvement plus related polishing
Issue: SPR-14747
2016-09-26 16:33:29 +02:00
Juergen Hoeller 49929f1e56 Clarified that getResource never returns null
(cherry picked from commit 36f7c7a)
2016-09-26 16:21:44 +02:00
Juergen Hoeller acdf139137 DefaultPersistenceUnitManager extracts jar file from default persistence unit root URL
Issue: SPR-14749
(cherry picked from commit bb7d207)
2016-09-26 16:21:33 +02:00
Juergen Hoeller 3346c594e4 YamlPropertiesFactoryBean consistently exposes String values
Issue: SPR-14737
(cherry picked from commit 74c6188)
2016-09-26 16:21:03 +02:00
Juergen Hoeller 0bb2cfe440 Latest dependency updates (Jackson 2.8.3, JavaMail 1.5.6, Jetty 9.3.12, Undertow 1.3.25) 2016-09-22 14:25:44 +02:00
Josh Long 11573b4ea4 fix spelling of word 'recommendation'
this PR fixes the spelling error for the word 'recommendation'
(cherry picked from commit 9b87ea0)
2016-09-22 14:25:25 +02:00
Spring Buildmaster 5934959b62 Next Development Version 2016-09-19 15:11:46 +00:00
Rossen Stoyanchev 81f6c22e51 Reset connection before delegating to handler
Resetting the connection first before invoking a failure callback on
the application handler ensures that any checks to isConnected will
return false.

Issue: SPR-14721
2016-09-19 09:06:11 -04:00
Stephane Nicoll 78a8245f4a Polish 2016-09-19 15:04:52 +02:00
Krzysztof Kosmatka 049861afb4 Documentation formatting fix
Removed unnecessary quotation marks that caused improper rendering
of in-line code.

Closes gh-1180
2016-09-19 15:04:39 +02:00
Krzysztof Kosmatka 3df7083f69 Add missing quotation mark
Closes gh-1181
2016-09-19 15:04:31 +02:00
Juergen Hoeller ca17edd5ac Revised checkResource implementation
Issue: SPR-14729
2016-09-18 21:04:37 +02:00
Sam Brannen c26bf871b7 Clean up warnings related to forthcoming removals in Tomcat 9
(cherry picked from commit b521aa8)
2016-09-18 21:04:29 +02:00
Sam Brannen 15d3e8c3e1 Introduce 'value' alias for @Bean's 'name' attribute
In order to simplify configuration for use cases involving @Bean where
only a bean name or aliases are supplied as an attribute, this commit
introduces a new 'value' attribute that is an @AliasFor 'name' in @Bean.

Issue: SPR-14728
(cherry picked from commit 8f62b63)
2016-09-18 21:04:25 +02:00
Brian Clozel 66b370e103 Check template availability in ScriptTemplateView
This commit overrides the `checkResource` implementation in
`ScriptTemplateView` in order to check if the template file resource is
available and if the resolver can then proceed with rendering the
template.

Issue: SPR-14729
Cherry-picked from: 97c9b05c15
2016-09-17 22:30:29 +02:00
Juergen Hoeller 2bbfbb1d50 What's New updated for significant refinements in 4.3.3 2016-09-16 14:31:53 +02:00
Juergen Hoeller ace25d4987 Polishing
(cherry picked from commit ed19dc7)
2016-09-16 14:30:41 +02:00
Juergen Hoeller 59cb9a4e60 Latest dependency updates (EhCache 3.1.2, Caffeine 2.3.3, Rome 1.7, Woodstox 5.0.3, Jettison 1.3.8) 2016-09-16 11:02:22 +02:00
Stephane Nicoll 0dce570157 Add Qualified element on RootBeanDefinition
Improve RootBeanDefinition to specify an AnnotatedElement that holds
qualifier information. When such element is present, any qualifier that
it defines will be used to find a matching candidate.

Issue: SPR-14725
(cherry picked from commit 2b0bf9f)
2016-09-16 11:02:03 +02:00
Juergen Hoeller 7ddaf49eb2 StringUtils.parseLocaleString accepts Java 7 variants
Issue: SPR-14718
(cherry picked from commit f24ce76)
2016-09-16 10:58:51 +02:00
Juergen Hoeller e947363a11 Timeout exceptions as RuntimeExceptions
Issue: SPR-14669
(cherry picked from commit 6dc1898)
2016-09-15 09:05:14 +02:00
Rossen Stoyanchev 5dbfe48d24 Improve async request timeout handling
Rather than setting the status to 503 directly from the timeout
interceptor which no longer seems to work reliably with Servlet
containers like Jetty even performing an additional ERROR dispatch back
to the original URL, we know rather set the DeferredResult to an
AsyncTimeoutException, which results in a dispatch and standard
handling within Spring MVC. This should be a more reliable way of
dealing with timeouts.

Issue: SPR-14669
2016-09-14 21:31:30 -04:00
Rossen Stoyanchev 07d5f8b123 Check both connection and connected flag
Issue: SPR-14703
2016-09-14 17:23:36 -04:00
kosmaty be99603f1b Fix doc style
Closes gh-1172
2016-09-14 11:08:29 +02:00
Juergen Hoeller 54db496815 Polishing
(cherry picked from commit 404e7cd)
2016-09-13 23:43:58 +02:00
Juergen Hoeller fbe7ddb640 PropertySourcesPropertyResolver does not log retrieved value by default
Issue: SPR-14709
2016-09-13 23:43:52 +02:00
Juergen Hoeller 55c37d2a57 Upgrade to Tomcat 8.5.5 2016-09-13 22:34:19 +02:00
Juergen Hoeller 4b445531f5 HibernateExceptionTranslator avoids JPA IllegalState/ArgumentException translation
Issue: SPR-14681
2016-09-13 22:32:57 +02:00
Juergen Hoeller 12afc263a4 HibernateTemplate reflectively calls getNamedQuery (for runtime compatibility with Hibernate 5.0/5.1 vs 5.2)
Issue: SPR-14676
2016-09-13 22:32:36 +02:00
Juergen Hoeller 040d131284 Polishing
(cherry picked from commit ce42ed4)
2016-09-13 22:31:47 +02:00
Juergen Hoeller 73bbe0849a Revised IllegalArgumentException handling for Formatter parse calls
Issue: SPR-14661
(cherry picked from commit c69e6a3)
2016-09-13 22:31:01 +02:00
Juergen Hoeller 09a0615df0 Consistent callbacks for TypeFilters, ImportSelectors and ImportBeanDefinitionRegistrars
Issue: SPR-14686
(cherry picked from commit 0c2e8a6)
2016-09-13 22:30:29 +02:00
Juergen Hoeller 669d5815c9 Configuration class processing uses MetadataReaderFactory for current ResourceLoader
Issue: SPR-14684
(cherry picked from commit 5405c07)
2016-09-13 22:30:12 +02:00
Juergen Hoeller bd24b97bd3 IdentityHashMap for scheduled tasks (avoiding hashCode calls on bean instances)
Issue: SPR-14666
(cherry picked from commit 480cd2c)
2016-09-13 22:29:59 +02:00
Juergen Hoeller db196ce5d8 Correct ISO DateTime example
Issue: SPR-14675
(cherry picked from commit d5c9cc6)
2016-09-13 22:28:28 +02:00
Juergen Hoeller 4396b211ce Avoid outdated Tibco workaround in shouldCommitAfterNoMessageReceived
Issue: SPR-14697
(cherry picked from commit edbc1e9)
2016-09-13 22:28:07 +02:00
Juergen Hoeller 367949e914 PropertyValue stores source object in common superclass field
Issue: SPR-8337
(cherry picked from commit fa820bc)
2016-09-13 22:27:17 +02:00
Juergen Hoeller ae2bbe7f19 MappingJackson2MessageConverter adds message id and destination to type resolution exception
Issue: SPR-14672
(cherry picked from commit 8c56606)
2016-09-13 22:26:37 +02:00
nkjackzhang 819e14f91b Fix typo
There is no attribute named `path` in `@RequestParam`, so I change it to
`name`.

Closes gh-1165
2016-09-10 07:49:48 +02:00
Brian Clozel fcf3ccba98 Fix default encoding in CONTRIBUTING documentation
Sources should be using UTF-8.

Issue: SPR-14674
Cherry-picked from: d1f60e3de1
2016-09-07 10:48:16 +02:00
nkjackzhang 558a10b54f Fix typo
Closes gh-1158
2016-09-07 09:38:00 +02:00
Brian Clozel 43c60a02f7 Fix response status check in ServletWrbRequest
Issue: SPR-14659
2016-09-06 19:13:03 +02:00
Brian Clozel 6501bc5d32 Align MVC checkNotModified with reactive support
Since SPR-14522, the web reactive framework supports checkNotModified
features. This commit aligns the existing MVC infrastructure with
web reactive's behavior.

Code duplication has been removed from `HttpEntityMethodProcessor`
but the Servlet 2.5 baseline is still respected.

Issue: SPR-14659
Cherry-picked from: cc5300c4d5
2016-09-06 18:17:47 +02:00
Brian Clozel f3dae0c9ad Mention AntPathMatcher regexp support
This commit documents the regexp support in `AntPathMatcher` when
matching for URL patterns. This support is also mentioned in places
where developers can register patterns for ViewControllers or resource
handlers.

Issue: SPR-14652
Cherry-picked from: a8ba065a6e
2016-09-02 11:40:11 +02:00
sylvainlaurent dc2cafc888 Fix class literal in instanceof
Closes gh-1151
2016-09-01 16:23:32 +02:00
Juergen Hoeller 49fc4923be Upgrade to JSR-354 API 1.0.1 and Jackson 2.8 javadocs 2016-09-01 12:56:25 +02:00
Juergen Hoeller efb5f17a60 Documentation updates around configuration classes
(cherry picked from commit aff914c)
2016-09-01 12:52:11 +02:00
Juergen Hoeller 086e764845 ResolvableType.java.forRawClass(Class) supports isAssignableFrom(ResolvableType) as well
Issue: SPR-14648
(cherry picked from commit 1a30252)
2016-08-31 14:57:27 +02:00
Juergen Hoeller c30290b43c @PathVariable supports 'required' attribute (for model attribute methods)
Issue: SPR-14646
(cherry picked from commit e08b1b7)
2016-08-31 14:57:21 +02:00
Brian Clozel d26421fe3b Fix missing ResourceHttpRequestHandler init in registry
Issue: SPR-14577
Cherry-picked from: 7a88776329
2016-08-31 10:47:18 +02:00
Juergen Hoeller 37670924f6 Polishing 2016-08-31 01:53:03 +02:00
Juergen Hoeller ee5143b54b Upgrade to Jackson 2.8.2 and Netty 4.1.5 2016-08-31 00:45:34 +02:00
Juergen Hoeller acbb2544bf Polishing
(cherry picked from commit 4ef428d)
2016-08-31 00:45:25 +02:00
Juergen Hoeller d8f7347000 Consistent comma splitting without regex overhead
Issue: SPR-14635
(cherry picked from commit 03609c1)
2016-08-31 00:44:52 +02:00
Juergen Hoeller 3b91dec462 ApplicationListenerMethodAdapter resolves order on construction
Issue: SPR-14642
(cherry picked from commit 58fa63f)
2016-08-31 00:44:43 +02:00
Juergen Hoeller 05f74b4218 CommonsMultipartResolver explicitly converts FileSizeLimitExceededException
Issue: SPR-14638
(cherry picked from commit 58ffca7)
2016-08-31 00:44:19 +02:00
Juergen Hoeller 8e98177fb3 Avoid collection lookups in StompCommand
Issue: SPR-14636
(cherry picked from commit 899ebd8)
2016-08-31 00:44:14 +02:00
Rossen Stoyanchev 815a3ad0de Relax ServletContext check for resource handling
This is a follow-up on commit fe4046 relaxing the expectation that a
ServletContext is present. Instead we check defensively and fall back
on PathExtensionContentNegotiationStrategy which can use JAF.

Issue: SPR-14577
2016-08-30 12:57:35 -04:00
Rossen Stoyanchev 5075dd4dfa Harden synchronization around SockJS heartbeats
Create an explicit heartbeat task with an experiration flag so that
it can be cancelled reliably vs relying on the ScheduledFutureTask
cancel method which may return true even if the task is already
running.

Issue: SPR-14356
2016-08-30 09:20:07 -04:00
Rossen Stoyanchev ca09dcbe89 Polish media type change in ResourceHttpRequestHandler 2016-08-29 19:48:06 -04:00
Rossen Stoyanchev 198a74d793 Support receipt on DISCONNECT with simple broker
Issue: SPR-14568
2016-08-29 18:30:17 -04:00
Rossen Stoyanchev fe404628e9 Fix media type regression in resource handling
Issue: SPR-14577
2016-08-29 16:39:07 -04:00
Juergen Hoeller 5a004c3b2a LiveBeansView exposes aliases as well
Issue: SPR-14632
(cherry picked from commit 57cb7c7)
2016-08-26 20:18:39 +02:00
Juergen Hoeller 430180aa96 Polishing 2016-08-26 18:33:13 +02:00
Juergen Hoeller e828be96f0 Polishing 2016-08-26 17:29:16 +02:00
Juergen Hoeller 52447efb97 Avoid getParameterType use with Oracle 12c driver by default
Issue: SPR-14629
Issue: SPR-14574
Issue: SPR-14191
2016-08-26 17:29:00 +02:00
Rossen Stoyanchev d09b0fe83a Support target type in JsonPath assertions
This change adds support for a target type in JsonPath assertions in
Spring MVC Test.

The existing assertValue(String expression, Object expectedValue)
transparently falls back on using an alternative JsonPath API that
allows specifying the target type to coerce to.

There is also a new overloaded method
assertValue(String expression, Matcher<T> matcher, Class<T> targetType)
for use with Hamcrest matchers where the target type can be specified.

Issue: SPR-14498
(cherry picked from commit 7fdb892)
2016-08-26 17:28:37 +02:00
Brian Clozel 798d8668a4 Fix server errors for invalid If-None-Match request headers
HttpEntityMethodProcessor should not throw IllegalArgumentExceptions for
invalid If-None-Match headers.

For those cases, this commit makes sure that both
`HttpEntityMethodProcessor` and `ServletWebRequest` have a consistent
behavior and stop processing the request as conditional and leave the
handler handle it.

Issue: SPR-14559
2016-08-26 15:33:02 +02:00
Juergen Hoeller 2a82b8fed9 Consistent use of Charset.forName over JDK 7 StandardCharsets in 4.x line 2016-08-26 13:11:39 +02:00
Juergen Hoeller 696f687419 Moved encodeHttpHeaderFieldParam method to HttpHeaders itself (including tests)
This commit also sets the test source encoding to UTF-8.

Issue: SPR-14547
(cherry picked from commit a8f7f75)
2016-08-26 12:55:34 +02:00
Brian Clozel 9b91b9db8c Add RFC5987 support for HTTP header field params
This commit adds support for HTTP header field parameters encoding, as
described in RFC5987.
Note that the default implementation still relies on US-ASCII encoding,
as the latest rfc7230 Section 3.2.4 says that:

> Newly defined header fields SHOULD limit their field values to
  US-ASCII octets

Issue: SPR-14547
Cherry-picked from: f2faf84f31
2016-08-25 14:39:07 +02:00
Juergen Hoeller 026473280b Polishing 2016-08-25 00:10:06 +02:00
Juergen Hoeller a7849b2861 DefaultListableBeanFactory does not trigger early candidate creation ahead of primary bean selection
Issue: SPR-14611
(cherry picked from commit c4fcdb6)
2016-08-24 23:37:59 +02:00
Juergen Hoeller 74bf659c56 GenericApplicationContext picks up ClassLoader from custom ResourceLoader
Issue: SPR-14626
(cherry picked from commit 405e74b)
2016-08-24 23:36:33 +02:00
Juergen Hoeller c2feedb7a2 Revised assertions in StompHeaderAccessor
Issue: SPR-14625
(cherry picked from commit f3f691c)
2016-08-24 23:36:23 +02:00
Juergen Hoeller 0735e9ba98 Avoid unnecessary String concatenation in StompSubProtocolHandler
Issue: SPR-14624
(cherry picked from commit 56b197b)
2016-08-24 23:36:13 +02:00
Juergen Hoeller ab686732d0 Refined exception message
Issue: SPR-14609
2016-08-24 15:05:43 +02:00
Juergen Hoeller 6d86437369 TransactionAspectSupport stores given PlatformTransactionManager instance as strong reference
Issue: SPR-14609
(cherry picked from commit 951ac5e)
2016-08-24 14:39:19 +02:00
Juergen Hoeller 184285ab27 Polishing 2016-08-24 13:01:54 +02:00
Juergen Hoeller 1e8065d040 Unit test for empty Access-Control-Request-Headers (Chrome 52)
Includes optimized method/header resolution in CorsConfiguration.

Issue: SPR-14617
(cherry picked from commit d047174)
2016-08-24 11:53:44 +02:00
Juergen Hoeller f735d12247 UnsatisfiedDependencyException avoids duplicate nested exception message
Issue: SPR-14607
(cherry picked from commit 93d2287)
2016-08-24 11:53:36 +02:00
Juergen Hoeller 7135bc2dc2 Reintroduced MessageMethodArgumentResolver default constructor
Issue: SPR-14616
(cherry picked from commit c4fff6d)
2016-08-24 11:53:30 +02:00
Stephane Nicoll 9044706796 Remove reference to PayloadApplicationEvent
Issue: SPR-14594
2016-08-19 14:22:52 +02:00
Stephane Nicoll 5f68da3153 Document support for @ManagedBean
Issue: SPR-14600
2016-08-19 13:53:07 +02:00
Juergen Hoeller 5222489a01 Various @since tags (and varargs on setInterceptors)
(cherry picked from commit aac0e63)
2016-08-18 12:40:22 +02:00
Juergen Hoeller 27f830f345 Polishing 2016-08-18 10:28:31 +02:00
Juergen Hoeller 8d7db8e450 DelegatingWebMvcConfiguration properly delegates extendHandlerExceptionResolvers
Also fixes the declared visibility of configurePathMatch and configureAsyncSupport.

Issue: SPR-14599
(cherry picked from commit d2e3a1a)
2016-08-18 09:53:15 +02:00
Juergen Hoeller da56758054 Updated note on CompilationCustomizer and CompilerConfiguration
Issue: SPR-14585
2016-08-17 22:31:13 +02:00
Juergen Hoeller 66dcc4b6db Upgrade to Caffeine 2.3.2 2016-08-17 22:29:21 +02:00
Juergen Hoeller 6eab5622c7 Renamed setDefaultPersistenceUnitRootLocation to setPersistenceUnitRootLocation
(cherry picked from commit f1ab37c)
2016-08-17 22:18:19 +02:00
Juergen Hoeller af53f3d6cf Upgrade to Gradle 2.14.1
Issue: SPR-14570
2016-08-17 21:35:32 +02:00
Juergen Hoeller 188e5327ee Removed duplicate NoHandlerFoundException entry
Issue: SPR-14598
(cherry picked from commit e9f48a4)
2016-08-17 21:30:41 +02:00
Juergen Hoeller 1932a9d729 Polishing
(cherry picked from commit de91b1a)
2016-08-17 21:30:30 +02:00
Juergen Hoeller c926ec477a Polishing 2016-08-17 17:47:14 +02:00
Juergen Hoeller 7b11fa18a1 Revised NoSuchBeanDefinitionException message for proper array class names
Issue: SPR-14595
(cherry picked from commit 022b013)
2016-08-17 17:47:14 +02:00
Juergen Hoeller e6cefdca25 RootBeanDefinition accepts ResolvableType for target type hint
Issue: SPR-14580
(cherry picked from commit 4b06b60)
2016-08-17 17:47:14 +02:00
Juergen Hoeller fbeff475b3 Consistent support for CompilationCustomizers as well as custom CompilerConfiguration
Issue: SPR-14585
(cherry picked from commit 6a0d9d3)
2016-08-17 17:47:14 +02:00
Stephane Nicoll d057099c17 Add setter for defaultPersistenceUnitRootLocation
This commit adds a setter for the default persistence unit's
defaultPersistenceUnitRootLocation attribute.
2016-08-17 17:41:47 +02:00
Stephane Nicoll 411700d7e6 Clarify use of Ehcache
Since we have a dedicated section regarding Ehcache that is only
applicable to Ehcache 2.x, this commit clarifies that Ehcache 3.x is
JSR-107 compliant and the JCache support should be used with it
rather than attempting to configure the Ehcache 2.x support.
2016-08-16 14:03:26 +02:00
Stephane Nicoll b4e9d918f2 Better document #result semantic
Commit 240f254 has introduced support for `java.util.Optional` in the
cache abstraction. If such type is present, the contained value is cached
if it is present.

This new feature slightly changed the semantic of `#result` that was
documented up till this commit as the "return value of the method
invocation". This is no longer true as `#result` for `Optional<T>`
refers to the `T` instance and not the `Optional` instance.

This commit clarifies both the javadoc and the documentation.

Issue: SPR-14587
2016-08-16 13:45:46 +02:00
Igor Mukhin 2756c364d2 Add aditional example to CronSequenceGenerator
CronSequenceGenerator supports comma separated expressions but does not
provide an example for it. This commit adds such an example.

Closes gh-1132
2016-08-16 11:43:15 +02:00
Rob Winch 43faabd4cc Fix HtmlUnitRequestBuilder merge
Previously invoking HtmlUnitRequestBuilder merge caused the pathInfo of
the parent to be corrupted. This could additional invocations with the
same parent.

This fix ensures that the parent is no longer directly used. Instead,
we create a copy of the parent by merging the parent that was passed in
with the copy.

Fixes SPR-14584
2016-08-12 20:49:48 -05:00
Juergen Hoeller a4a71a8904 Polishing 2016-08-11 23:45:50 +02:00
Juergen Hoeller e23ac031ff Avoid stack overflow in case of chained factory-bean references to FactoryBean class
Issue: SPR-14551
(cherry picked from commit 8b5d355)
2016-08-11 23:25:41 +02:00
Juergen Hoeller 79a56967a1 PersistenceAnnotationBeanPostProcessor obtains default EntityManagerFactory via getBean(Class) algorithm
Issue: SPR-7549
(cherry picked from commit 6157fad)
2016-08-11 23:25:35 +02:00
Juergen Hoeller 0bc0453700 Polishing 2016-08-10 16:59:22 +02:00
Juergen Hoeller 35e247aa26 Polishing 2016-08-10 16:21:35 +02:00
Juergen Hoeller 67ba187b6f Polishing
(cherry picked from commit 59a24b4)
2016-08-10 14:57:50 +02:00
Juergen Hoeller 67f0b1986c Consistent spelling for StandaloneMockMvcBuilder's addPlaceholderValue
(cherry picked from commit a4b6682)
2016-08-10 14:57:43 +02:00
Stephane Nicoll 60e0177d00 Fix typo
See gh-1129
2016-08-10 10:46:43 +02:00
Juergen Hoeller 4543a28e51 MethodBasedEvaluationContext reliably exposes varargs
Issue: SPR-14554
(cherry picked from commit fae503d)
2016-08-09 21:31:29 +02:00
Juergen Hoeller aade2d1ec9 Polishing
(cherry picked from commit 9475c06)
2016-08-09 12:37:07 +02:00
Juergen Hoeller 4627545a3b Polishing
(cherry picked from commit eae079a)
2016-08-09 11:03:51 +02:00
Juergen Hoeller e2ba7c9b8c MockClientHttpResponse closes body stream on close()
Issue: SPR-14563
(cherry picked from commit 47e9360)
2016-08-09 11:03:46 +02:00
Juergen Hoeller 6f5596ac5c Upgrade to Hibernate ORM 5.2.2 and Undertow 1.3.24 2016-08-08 16:07:34 +02:00
Juergen Hoeller 7d1c2f191a Consistent default connection release mode with Hibernate 5.1
Issue: SPR-14548
2016-08-08 14:27:24 +02:00
Juergen Hoeller 4ada571384 PathEditor tries file system path in case of non-existing resource
Issue: SPR-14549
(cherry picked from commit d69afaa)
2016-08-08 14:22:46 +02:00
Juergen Hoeller ad8ebbaa05 Test injection for @Lookup-declaring bean
Issue: SPR-14550
(cherry picked from commit d128830)
2016-08-08 14:22:42 +02:00
Stephane Nicoll 4854989db4 Polish Javadoc
Issue: SPR-14552
2016-08-06 17:17:25 +02:00
Sebastien Deleuze 7c5050cf80 Prevent StackOverflowError in AbstractJackson2HttpMessageConverter
Issue: SPR-14520
2016-08-04 11:28:20 -07:00
Spring Buildmaster 14ae8be547 Next Development Version 2016-07-28 08:26:01 +00:00
Juergen Hoeller ff878ea9dc ConfigurationClassParser uses unified ImportStack with chained import analysis
Issue: SPR-14517
(cherry picked from commit d96a66a)
2016-07-28 00:13:05 +02:00
Juergen Hoeller 7021a4be44 JndiPropertySource defensively skips invalid JNDI lookup for property name with colon in resource-ref mode
Issue: SPR-14518
(cherry picked from commit 328e04f)
2016-07-28 00:12:50 +02:00
Juergen Hoeller 5c4737c3d0 Upgrade to Netty 4.1.4 2016-07-27 16:49:37 +02:00
Juergen Hoeller fbf3807af1 Polishing
(cherry picked from commit 5db4495)
2016-07-27 16:49:18 +02:00
Juergen Hoeller 703c37ec88 Isolated circular import detection for scanned configuration classes
Issue: SPR-14517
(cherry picked from commit 316244d)
2016-07-27 16:49:04 +02:00
Juergen Hoeller 96440878bb Polishing 2016-07-27 13:00:30 +02:00
Juergen Hoeller b5c11ffb1c Expose DefaultSubscriptionRegistry's cache limit through SimpleBrokerMessageHandler and MessageBrokerRegistry
Issue: SPR-14516
(cherry picked from commit 6d5af60)
2016-07-27 12:34:28 +02:00
Juergen Hoeller 7f5b323d50 Upgrade to Jetty 9.3.11 (includes fixed Quartz javadoc URL) 2016-07-26 22:19:56 +02:00
Juergen Hoeller 67176e2b75 TransactionAspectSupport avoids hard references to transaction manager beans
Issue: SPR-14511
(cherry picked from commit 02374d7)
2016-07-26 21:46:49 +02:00
Juergen Hoeller 79f3cf3263 Build against Undertow 1.3.x in 4.3.x branch (retaining runtime compatibility Undertow 1.4)
Issue: SPR-14328
2016-07-26 10:08:06 +02:00
Juergen Hoeller 9ee1dc79fd Deprecate JpaSystemException(PersistenceException) constructor to prepare for removal in Spring 5
Issue: SPR-13827
2016-07-26 01:29:51 +02:00
Juergen Hoeller 9e2c34dfa6 Fixed ConcurrentMap declaration
(cherry picked from commit 23135b1)
2016-07-26 00:28:40 +02:00
Juergen Hoeller cc93c2a559 Polishing 2016-07-26 00:03:21 +02:00
Juergen Hoeller 15c7044c4d Upgrade to EhCache 3.1.1 and OkHttp 3.4.1 2016-07-25 15:20:08 +02:00
Juergen Hoeller 0ef80d3579 JasperReportsMultiFormatViewTests does not check for CUSTOM_COMPILATION anymore
Issue: SPR-10423
2016-07-25 15:19:50 +02:00
Juergen Hoeller 95c2e0a996 Upgrade JiBX (and BCEL) towards support of 1.8 bytecode level
This commit also drops the now-unused CUSTOM_COMPILATION test group and the outdated JavaVersion class.

Issue: SPR-10423
(cherry picked from commit 01110f6)
2016-07-25 14:58:43 +02:00
Juergen Hoeller da3e8611e1 Upgrade JiBX (and BCEL) towards support of 1.8 bytecode level
Issue: SPR-10423
2016-07-25 13:08:46 +02:00
Juergen Hoeller 64595597f3 LinkedCaseInsensitiveMap properly overrides HashMap.clone()
Issue: SPR-14509
(cherry picked from commit dd65f7a)
2016-07-25 12:14:51 +02:00
Juergen Hoeller 82f2983cd4 Consistent throwing of BeanNotOfRequiredTypeException even for existing proxy
Issue: SPR-14504
(cherry picked from commit 4a85309)
2016-07-24 15:47:06 +02:00
Juergen Hoeller 9451177c35 Polishing
(cherry picked from commit 382a931)
2016-07-22 22:45:14 +02:00
Juergen Hoeller 9ed087d5da Consistent support for multiple Accept headers
Issue: SPR-14506
(cherry picked from commit e59a599)
2016-07-22 22:45:04 +02:00
Juergen Hoeller 77f22e9674 DataSource adapters expose setCatalog/setSchema next to setUsername/setPassword
Issue: SPR-14501
(cherry picked from commit 610bdf1)
2016-07-21 14:13:37 +02:00
Juergen Hoeller 8ccfdbbcf9 ResourcePatternUtils.getResourcePatternResolver actually accepts null argument
Issue: SPR-14500
(cherry picked from commit e756a5b)
2016-07-21 14:09:32 +02:00
Juergen Hoeller 5a92aa4e06 Polishing
(cherry picked from commit a39276a)
2016-07-20 23:23:30 +02:00
Juergen Hoeller 7b1010cf61 Polishing 2016-07-20 22:31:45 +02:00
Juergen Hoeller 45b2f5bac4 Upgrade to Jackson 2.8.1 2016-07-20 22:31:25 +02:00
Juergen Hoeller 36e1c82ef5 Backported refinements and polishing 2016-07-20 21:46:25 +02:00
Juergen Hoeller 503d65d570 Avoid JDK proxy against CGLIB Factory interface and assert required type when resolving dependency
Issue: SPR-14478
(cherry picked from commit 0e3f0bd)
2016-07-20 21:45:41 +02:00
Juergen Hoeller fe17f8da41 BeanWrapperImpl.setBeanInstance correctly exposes root object
Issue: SPR-14474
(cherry picked from commit 938b56c)
2016-07-20 21:44:46 +02:00
Juergen Hoeller b583aa1579 Avoid dependency on WebUtils for extracting file extension
Issue: SPR-14479
(cherry picked from commit adc595b)
2016-07-20 21:44:37 +02:00
Juergen Hoeller e0d81b97bb SerializableTypeWrapper reobtains type accessors from declaring interface
Issue: SPR-14487
(cherry picked from commit 8580483)
2016-07-20 21:41:42 +02:00
Juergen Hoeller 90752f9d87 Deprecate mock.staticmock package
Issue: SPR-14485
2016-07-20 21:41:30 +02:00
Juergen Hoeller 3663aa675a GenericSqlQuery configured with RowMapper instance
Issue: SPR-14489
(cherry picked from commit 7287bae)
2016-07-20 21:40:48 +02:00
Juergen Hoeller 1ca4b81856 Reinstated tests for implicit aliases
Issue: SPR-14437
(cherry picked from commit 5ea8c26)
2016-07-20 21:40:33 +02:00
Juergen Hoeller 4e7e06f549 Reliably pass CurrentTenantIdentifierResolver to SessionFactory
Issue: SPR-14476
2016-07-20 21:40:26 +02:00
Sebastien Deleuze b2f0bdb0f4 Polishing
Issue: SPR-14470
2016-07-20 09:16:50 +02:00
Rossen Stoyanchev d98bd34200 Remove isAsyncStarted assertion
Issue: SPR-14444
2016-07-19 16:44:46 -04:00
Sebastien Deleuze 940bdd878e Fix ParameterizedType + contextClass support in Jackson converter
Issue: SPR-14470
2016-07-19 18:10:51 +02:00
Vladimir L df556333a8 Add StreamingResponseBody MockMvc sample tests
Issue: SPR-14456
(cherry picked from 7da63c)
2016-07-19 10:48:29 -04:00
Stephane Nicoll 116f05eda6 Revert "Upgrade to EJB 3.1" 2016-07-18 13:37:43 +02:00
Stephane Nicoll b187bbeca3 Upgrade to EJB 3.1 2016-07-18 13:22:54 +02:00
Do Nhu Vy 479a83b628 Fix broken hyperlink
Closes gh-1114
2016-07-18 08:17:49 +02:00
Fredrik Sundberg 1c18100143 Fix javadoc reference
Method is called nextBackOff() and not nextBackOffMillis().

Closes gh-1115
2016-07-18 08:15:41 +02:00
Juergen Hoeller 5d3c0f33f6 Upgrade to Netty 4.1.3 and Tomcat 8.5.4 2016-07-15 22:47:22 +02:00
Juergen Hoeller afe106e254 Polishing 2016-07-15 22:47:12 +02:00
Juergen Hoeller 69dd40ec89 Javadoc fixes and pruning of deprecated references 2016-07-15 22:47:05 +02:00
Sam Brannen dee50d5e28 Polish annotation utils
(cherry picked from commit 177f4ec)
2016-07-15 22:21:23 +02:00
Juergen Hoeller 9e93403857 ConfigurationClassParser load annotations through source class loader
Issue: SPR-10343
2016-07-15 16:02:06 +02:00
Juergen Hoeller 12bff6b3a0 Velocity deprecation note in reference documentation
Issue: SPR-14460
2016-07-15 15:44:13 +02:00
Juergen Hoeller 70e666b4a3 MultipartResolutionDelegate's resolveMultipartArgument properly operates on Servlet 2.5
Issue: SPR-14461
2016-07-15 15:42:32 +02:00
Juergen Hoeller 29f980ec72 Unwrap JPA PersistenceException on flush failure (for Hibernate 5.2)
Issue: SPR-14457
2016-07-15 15:40:38 +02:00
Juergen Hoeller 1d39d762f0 HibernateExceptionTranslator converts JPA exceptions as well (for Hibernate 5.2)
Issue: SPR-14455
2016-07-15 15:40:26 +02:00
Juergen Hoeller 4d6d5e0ddd Consistent alias processing behind AnnotatedTypeMetadata abstraction (also for ASM)
Issue: SPR-14427
(cherry picked from commit 3d3407c)
2016-07-15 15:40:01 +02:00
Juergen Hoeller 4ea5f070a4 MessageHeaderAccessor properly removes header even in case of null value
Issue: SPR-14468
(cherry picked from commit b166358)
2016-07-15 15:39:33 +02:00
Juergen Hoeller da59b4da9b CronSequenceGenerator prevents stack overflow in case of inverted range
Issue: SPR-14462
(cherry picked from commit e431624)
2016-07-15 15:39:17 +02:00
Juergen Hoeller 0065a160cc StandardTypeConverter initializes default ConversionService against volatile field
Issue: SPR-14465
(cherry picked from commit 6d91d54)
2016-07-15 15:39:09 +02:00
Juergen Hoeller 52f46c7fea Aspect actually applies in PersistenceExceptionTranslationPostProcessorTests
Issue: SPR-14457
(cherry picked from commit 04e9c2b)
2016-07-15 15:38:44 +02:00
Juergen Hoeller f0a826ec0c AbstractHandlerMethodMapping adds type+method info to getMappingForMethod exceptions
Issue: SPR-14452
(cherry picked from commit 8ccd727)
2016-07-15 15:38:23 +02:00
Juergen Hoeller 5c3c0f73c1 Configurable UrlPathHelper in PathExtensionContentNegotiationStrategy
This commit also aligns ResourceUrlProvider's and RequestMappingInfo's UrlPathHelper setter/getter signatures.

Issue: SPR-14454
(cherry picked from commit 84afc60)
2016-07-15 15:37:56 +02:00
Juergen Hoeller be0b71ce31 Fixed typo: "occured"->"occurred"
(cherry picked from commit c43e749)
2016-07-15 15:37:11 +02:00
Juergen Hoeller f85d48dd31 Added PathEditor for NIO file system resolution
Issue: SPR-14436
(cherry picked from commit 23c2b6a)
2016-07-15 15:37:02 +02:00
Juergen Hoeller a1b58ee601 DigestUtils processes InputStream with buffered read instead of full copy
Issue: SPR-14427
(cherry picked from commit 61db8e9)
2016-07-15 15:34:36 +02:00
Juergen Hoeller e30429051d Polishing
(cherry picked from commit 6aa5931)
2016-07-15 15:34:27 +02:00
fisache 942ead75e2 Polish doc
Closes gh-1108
2016-07-14 19:16:20 +02:00
nkjackzhang 453688f6df Polish doc
Closes gh-1110
2016-07-14 11:57:41 +02:00
Stephane Nicoll 7d7a161102 Polish contribution
Closes gh-1070
2016-07-14 11:26:31 +02:00
spodgurskiy aaa223ae66 Fix MethodBasedEvaluationContext.lazyLoadArguments
This commit fix a potential `ArrayIndexOutOfBoundsException` if
`lazyLoadArguments` is called with an empty variable argument.

See gh-1070
2016-07-14 11:26:20 +02:00
Brian Clozel d11c624fb0 Polish AntPathMatcher.setTrimTokens javadoc
Issue: SPR-14247
Cherry-picked from 147a35f
2016-07-12 14:50:00 +02:00
nkjackzhang 275e51b19d Polish doc
Closes gh-1107
2016-07-12 08:51:35 +02:00
Stephane Nicoll ab62edeeaa Fix NoOpCache handling of get(key,callable)
This commit fixes the method that takes a Callable to actually always
invoke it rather than returning null.

Issue: SPR-14445
2016-07-11 10:36:51 +02:00
Sam Brannen 813108a928 Ensure TestContextManager always tracks after-class exception
This commit fixes a minor bug introduced in 0adc4921ed.

Issue: SPR-14447
2016-07-10 16:00:30 +02:00
Juergen Hoeller 3c14911401 Polishing 2016-07-06 17:59:49 +02:00
Juergen Hoeller 4337f14627 Upgrade to Jackson 2.8 GA 2016-07-06 17:42:10 +02:00
Juergen Hoeller 92d78c10a2 Polishing (backported from master) 2016-07-06 17:13:18 +02:00
Juergen Hoeller 16d5ba9b3a Restored binary compatibility with Hibernate 5.0/5.1's Query type
Issue: SPR-14425
2016-07-06 16:11:15 +02:00
Juergen Hoeller 52065a736b Avoid canonicalName call for already-seen bean name
Issue: SPR-14433
(cherry picked from commit 5890758)
2016-07-06 16:09:32 +02:00
Stephane Nicoll 11cb109114 Upgrade copyright 2016-07-04 12:45:34 +02:00
Stephane Nicoll d7eadd41d6 Switch to 4.3.2.BUILD-SNAPSHOT 2016-07-04 12:28:13 +02:00
2040 changed files with 54176 additions and 34894 deletions
+4 -5
View File
@@ -88,15 +88,14 @@ present in the framework.
1. Preserve existing formatting; i.e. do not reformat code for its own sake
1. Search the codebase using `git grep` and other tools to discover common
naming conventions, etc.
1. Latin-1 (ISO-8859-1) encoding for Java sources; use `native2ascii` to convert
if necessary
1. UTF-8 encoding for Java sources
### Add Apache license header to all new classes
```java
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -124,11 +123,11 @@ modified a file in 2015 whose header still reads:
* Copyright 2002-2011 the original author or authors.
```
Then be sure to update it to 2015 accordingly:
Then be sure to update it to 2016 accordingly:
```java
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 the original author or authors.
```
### Use @since tags for newly-added public API types and methods
+126 -126
View File
@@ -32,51 +32,52 @@ configure(allprojects) { project ->
version = qualifyVersionIfNecessary(version)
ext.aspectjVersion = "1.8.9"
ext.caffeineVersion = "2.3.1"
ext.caffeineVersion = "2.3.5"
ext.eclipselinkVersion = "2.4.2"
ext.ehcacheVersion = "2.10.2"
ext.ehcacheVersion = "2.10.4"
ext.ehcachejcacheVersion = "1.0.1"
ext.ehcache3Version = "3.1.0"
ext.ehcache3Version = "3.1.4"
ext.ejbVersion = "3.0"
ext.fileuploadVersion = "1.3.2"
ext.fileuploadVersion = "1.3.3"
ext.freemarkerVersion = "2.3.23"
ext.groovyVersion = "2.4.7"
ext.gsonVersion = "2.7"
ext.guavaVersion = "19.0"
ext.groovyVersion = "2.4.15"
ext.gsonVersion = "2.8.5"
ext.guavaVersion = "20.0"
ext.hamcrestVersion = "1.3"
ext.hibernate3Version = "3.6.10.Final"
ext.hibernate4Version = "4.3.11.Final"
ext.hibernate5Version = "5.2.1.Final"
ext.hibernate5Version = "5.2.10.Final"
ext.hibval4Version = "4.3.2.Final"
ext.hibval5Version = "5.2.4.Final"
ext.hibval5Version = "5.2.5.Final"
ext.hsqldbVersion = "2.3.4"
ext.httpasyncVersion = "4.1.2"
ext.httpclientVersion = "4.5.2"
ext.jackson2Version = "2.8.0.rc2"
ext.httpasyncVersion = "4.1.4"
ext.httpclientVersion = "4.5.6"
ext.jackson2Version = "2.8.11.3"
ext.jasperreportsVersion = "6.2.1" // our tests fail with JR-internal NPEs against 6.2.2 and higher
ext.javamailVersion = "1.5.5"
ext.jettyVersion = "9.3.10.v20160621"
ext.jodaVersion = "2.9.4"
ext.jrubyVersion = "1.7.25" // JRuby 9000 only supported through JSR-223 (StandardScriptFactory)
ext.javamailVersion = "1.5.6"
ext.jettyVersion = "9.3.14.v20161028" // as of 9.3.15, Jetty has hard Servlet 3.1 requirement
ext.jetty94Version = "9.4.6.v20170531" // for spring-websocket support, optimized for Jetty 9.4
ext.jodaVersion = "2.9.9"
ext.jrubyVersion = "1.7.27" // JRuby 9000 primarily supported through JSR-223 (StandardScriptFactory)
ext.jtaVersion = "1.2"
ext.junitVersion = "4.12"
ext.log4jVersion = "1.2.17"
ext.nettyVersion = "4.1.1.Final"
ext.nettyVersion = "4.1.32.Final"
ext.okhttpVersion = "2.7.5"
ext.okhttp3Version = "3.3.1"
ext.openjpaVersion = "2.4.1"
ext.poiVersion = "3.14"
ext.okhttp3Version = "3.8.1"
ext.openjpaVersion = "2.4.2"
ext.poiVersion = "3.17"
ext.reactorVersion = "2.0.8.RELEASE"
ext.romeVersion = "1.6.0"
ext.slf4jVersion = "1.7.21"
ext.romeVersion = "1.7.4"
ext.slf4jVersion = "1.7.25"
ext.snakeyamlVersion = "1.17"
ext.snifferVersion = "1.15"
ext.snifferVersion = "1.17"
ext.testngVersion = "6.9.10"
ext.tiles2Version = "2.2.2"
ext.tiles3Version = "3.0.5"
ext.tomcatVersion = "8.5.3"
ext.tiles3Version = "3.0.8"
ext.tomcatVersion = "8.5.37"
ext.tyrusVersion = "1.3.5" // constrained by WebLogic 12.1.3 support
ext.undertowVersion = "1.4.0.CR2"
ext.undertowVersion = "1.3.33.Final"
ext.xmlunitVersion = "1.6"
ext.xstreamVersion = "1.4.9"
@@ -110,11 +111,13 @@ configure(allprojects) { project ->
compileJava {
sourceCompatibility = 1.6
targetCompatibility = 1.6
options.encoding = 'UTF-8'
}
compileTestJava {
sourceCompatibility = 1.8
targetCompatibility = 1.8
options.encoding = 'UTF-8'
options.compilerArgs += "-parameters"
}
@@ -199,11 +202,12 @@ configure(allprojects) { project ->
"http://www.eclipse.org/aspectj/doc/released/aspectj5rt-api/",
"http://ehcache.org/apidocs/${ehcacheVersion}",
"http://ehcache.org/apidocs/${ehcache3Version}",
"http://quartz-scheduler.org/api/2.2.0/",
"http://fasterxml.github.io/jackson-core/javadoc/2.7/",
"http://fasterxml.github.io/jackson-databind/javadoc/2.7/",
"http://fasterxml.github.io/jackson-dataformat-xml/javadoc/2.7/",
"http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/"
"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/",
"https://junit.org/junit4/javadoc/${junitVersion}/"
] as String[]
}
@@ -214,7 +218,6 @@ configure(subprojects - project(":spring-build-src")) { subproject ->
configurations {
jacoco
}
dependencies {
jacoco("org.jacoco:org.jacoco.agent:0.7.5.201505241946:runtime")
}
@@ -248,16 +251,16 @@ configure(subprojects - project(":spring-build-src")) { subproject ->
options.links(project.ext.javadocLinks)
options.addStringOption('Xdoclint:none', '-quiet')
// suppress warnings due to cross-module @see and @link references;
// note that global 'api' task does display all warnings.
// Suppress warnings due to cross-module @see and @link references.
// Note that global 'api' task does display all warnings.
logging.captureStandardError LogLevel.INFO
logging.captureStandardOutput LogLevel.INFO // suppress "## warnings" message
logging.captureStandardOutput LogLevel.INFO // suppress "## warnings" message
}
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
// don't include or exclude anything explicitly by default. See SPR-12085.
// Don't include or exclude anything explicitly by default. See SPR-12085.
}
task javadocJar(type: Jar) {
@@ -273,6 +276,7 @@ configure(subprojects - project(":spring-build-src")) { subproject ->
project("spring-build-src") {
description = "Exposes gradle buildSrc for IDE support"
apply plugin: "groovy"
dependencies {
@@ -286,12 +290,11 @@ project("spring-build-src") {
project("spring-core") {
description = "Spring Core"
// As of Spring 4.0.3, spring-core includes asm 5.x and repackages cglib 3.2, inlining
// both into the spring-core jar. cglib 3.2 itself depends on asm 5.x and is therefore
// 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.4"
def objenesisVersion = "2.4"
// 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.6"
def objenesisVersion = "2.6"
configurations {
jarjar
@@ -311,9 +314,9 @@ project("spring-core") {
configurations.cglib.each { originalJar ->
zipfileset(src: originalJar)
}
// repackage net.sf.cglib => org.springframework.cglib
// Repackage net.sf.cglib => org.springframework.cglib
rule(pattern: "net.sf.cglib.**", result: "org.springframework.cglib.@1")
// as mentioned above, transform cglib"s internal asm dependencies from
// As mentioned above, transform cglib's internal asm dependencies from
// org.objectweb.asm => org.springframework.asm. Doing this counts on the
// the fact that Spring and cglib depend on the same version of asm!
rule(pattern: "org.objectweb.asm.**", result: "org.springframework.asm.@1")
@@ -334,7 +337,7 @@ project("spring-core") {
configurations.objenesis.each { originalJar ->
zipfileset(src: originalJar)
}
// repackage org.objenesis => org.springframework.objenesis
// Repackage org.objenesis => org.springframework.objenesis
rule(pattern: "org.objenesis.**", result: "org.springframework.objenesis.@1")
}
}
@@ -351,17 +354,17 @@ project("spring-core") {
compile("commons-logging:commons-logging:1.2")
optional("commons-codec:commons-codec:1.10")
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
optional("net.sf.jopt-simple:jopt-simple:5.0.2")
optional("net.sf.jopt-simple:jopt-simple:5.0.3")
optional("log4j:log4j:${log4jVersion}")
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
testCompile("xmlunit:xmlunit:${xmlunitVersion}")
testCompile("com.fasterxml.woodstox:woodstox-core:5.0.2") {
testCompile("com.fasterxml.woodstox:woodstox-core:5.0.3") {
exclude group: "stax", module: "stax-api"
}
}
jar {
// inline repackaged cglib classes directly into the spring-core jar
// Inline repackaged cglib classes directly into spring-core jar
dependsOn cglibRepackJar
from(zipTree(cglibRepackJar.archivePath)) {
include "org/springframework/cglib/**"
@@ -390,6 +393,7 @@ project("spring-beans") {
project("spring-beans-groovy") {
description "Groovy Bean Definitions"
merge.into = project(":spring-beans")
apply plugin: "groovy"
@@ -398,8 +402,8 @@ project("spring-beans-groovy") {
optional("org.codehaus.groovy:groovy-all:${groovyVersion}")
}
// this module's Java and Groovy sources need to be compiled together
compileJava.enabled=false
// This module's Java and Groovy sources need to be compiled together.
compileJava.enabled = false
sourceSets {
main {
groovy {
@@ -465,26 +469,27 @@ project("spring-instrument-tomcat") {
project("spring-context") {
description = "Spring Context"
apply plugin: "groovy"
dependencies {
compile(project(":spring-aop"))
compile(project(":spring-beans"))
compile(project(":spring-expression"))
compile(project(":spring-core"))
compile(project(":spring-expression"))
compile(files(project(":spring-core").cglibRepackJar))
optional(project(":spring-instrument"))
optional("javax.inject:javax.inject:1")
optional("javax.ejb:ejb-api:${ejbVersion}")
optional("javax.enterprise.concurrent:javax.enterprise.concurrent-api:1.0")
optional("javax.money:money-api:1.0")
optional("javax.money:money-api:1.0.1")
optional("org.eclipse.persistence:javax.persistence:2.0.0")
optional("javax.validation:validation-api:1.0.0.GA")
optional("org.hibernate:hibernate-validator:${hibval4Version}")
optional("joda-time:joda-time:${jodaVersion}")
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
optional("org.codehaus.groovy:groovy-all:${groovyVersion}")
optional("org.beanshell:bsh:2.0b4")
optional("org.beanshell:bsh:2.0b5")
optional("org.jruby:jruby:${jrubyVersion}")
testCompile("javax.inject:javax.inject-tck:1")
testCompile("org.javamoney:moneta:1.1")
@@ -494,13 +499,44 @@ project("spring-context") {
}
}
project("spring-oxm") {
description = "Spring Object/XML Marshalling"
apply from: "oxm.gradle"
dependencies {
compile(project(":spring-beans"))
compile(project(":spring-core"))
optional("org.codehaus.castor:castor-xml:1.4.1") {
exclude group: 'stax', module: 'stax-api'
exclude group: "org.springframework", module: "spring-context"
}
optional("org.apache.xmlbeans:xmlbeans:2.6.0") {
exclude group: 'stax', module: 'stax-api'
}
optional("com.thoughtworks.xstream:xstream:${xstreamVersion}") {
exclude group: 'xpp3', module: 'xpp3_min'
exclude group: 'xmlpull', module: 'xmlpull'
}
optional("org.jibx:jibx-run:1.2.6")
testCompile(project(":spring-context"))
testCompile("org.ogce:xpp3:1.1.6")
testCompile("org.codehaus.jettison:jettison:1.3.8") {
exclude group: 'stax', module: 'stax-api'
}
testCompile("xmlunit:xmlunit:${xmlunitVersion}")
testCompile(files(genCastor.classesDir).builtBy(genCastor))
testCompile(files(genJaxb.classesDir).builtBy(genJaxb))
testCompile(files(genXmlbeans.classesDir).builtBy(genXmlbeans))
}
}
project("spring-messaging") {
description = "Spring Messaging"
dependencies {
compile(project(":spring-beans"))
compile(project(":spring-core"))
compile(project(":spring-context"))
compile(project(":spring-core"))
optional(project(":spring-oxm"))
optional("io.projectreactor:reactor-core:${reactorVersion}")
optional("io.projectreactor:reactor-net:${reactorVersion}") {
@@ -552,54 +588,14 @@ project("spring-tx") {
}
}
project("spring-oxm") {
description = "Spring Object/XML Marshalling"
apply from: "oxm.gradle"
compileTestJava {
// necessary to avoid java.lang.VerifyError on jibx compilation
// see http://jira.codehaus.org/browse/JIBX-465
sourceCompatibility = 1.6
targetCompatibility = 1.6
}
dependencies {
compile(project(":spring-beans"))
compile(project(":spring-core"))
optional("org.codehaus.castor:castor-xml:1.4.1") {
exclude group: 'stax', module: 'stax-api'
exclude group: "org.springframework", module: "spring-context"
}
optional("org.apache.xmlbeans:xmlbeans:2.6.0") {
exclude group: 'stax', module: 'stax-api'
}
optional("com.thoughtworks.xstream:xstream:${xstreamVersion}") {
exclude group: 'xpp3', module: 'xpp3_min'
exclude group: 'xmlpull', module: 'xmlpull'
}
optional("org.jibx:jibx-run:1.2.6")
testCompile(project(":spring-context"))
testCompile("xmlunit:xmlunit:${xmlunitVersion}")
testCompile("xpp3:xpp3:1.1.4c")
testCompile("org.codehaus.jettison:jettison:1.3.7") {
exclude group: 'stax', module: 'stax-api'
}
if (compileTestJava.enabled) {
testCompile(files(genCastor.classesDir).builtBy(genCastor))
testCompile(files(genJaxb.classesDir).builtBy(genJaxb))
testCompile(files(genXmlbeans.classesDir).builtBy(genXmlbeans))
}
}
}
project("spring-jms") {
description = "Spring JMS"
dependencies {
compile(project(":spring-core"))
compile(project(":spring-beans"))
compile(project(":spring-aop"))
compile(project(":spring-beans"))
compile(project(":spring-context"))
compile(project(":spring-core"))
compile(project(":spring-messaging"))
compile(project(":spring-tx"))
provided("javax.jms:jms-api:1.1-rev-1")
@@ -621,9 +617,9 @@ project("spring-jdbc") {
optional("javax.transaction:javax.transaction-api:${jtaVersion}")
optional("com.mchange:c3p0:0.9.5.2")
optional("org.hsqldb:hsqldb:${hsqldbVersion}")
optional("com.h2database:h2:1.4.192")
optional("org.apache.derby:derby:10.12.1.1")
optional("org.apache.derby:derbyclient:10.12.1.1")
optional("com.h2database:h2:1.4.193")
optional("org.apache.derby:derby:10.13.1.1")
optional("org.apache.derby:derbyclient:10.13.1.1")
}
}
@@ -631,9 +627,9 @@ project("spring-context-support") {
description = "Spring Context Support"
dependencies {
compile(project(":spring-core"))
compile(project(":spring-beans"))
compile(project(":spring-context"))
compile(project(":spring-core"))
optional(project(":spring-jdbc")) // for Quartz support
optional(project(":spring-tx")) // for Quartz support
optional("javax.mail:javax.mail-api:${javamailVersion}")
@@ -662,11 +658,14 @@ project("spring-context-support") {
testCompile("org.slf4j:slf4j-api:${slf4jVersion}")
testRuntime("com.sun.mail:javax.mail:${javamailVersion}")
testRuntime("org.ehcache:jcache:${ehcachejcacheVersion}")
testRuntime("org.ehcache:ehcache:${ehcache3Version}")
testRuntime("org.terracotta:management-model:2.3.0")
}
}
project("spring-web") {
description = "Spring Web"
apply plugin: "groovy"
// Re-generate Protobuf classes from *.proto files and move them in test sources
@@ -705,7 +704,7 @@ project("spring-web") {
optional("com.squareup.okhttp:okhttp:${okhttpVersion}")
optional("com.squareup.okhttp3:okhttp:${okhttp3Version}")
optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
optional("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${jackson2Version}")
optional("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.8.11")
optional("com.google.code.gson:gson:${gsonVersion}")
optional("com.rometools:rome:${romeVersion}")
optional("org.eclipse.jetty:jetty-servlet:${jettyVersion}") {
@@ -721,12 +720,14 @@ project("spring-web") {
testCompile(project(":spring-context-support")) // for JafMediaTypeFactory
testCompile("xmlunit:xmlunit:${xmlunitVersion}")
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
testCompile("org.skyscreamer:jsonassert:1.4.0")
testCompile("org.apache.taglibs:taglibs-standard-jstlel:1.2.1") {
exclude group: "org.apache.taglibs", module: "taglibs-standard-spec"
}
testCompile("com.fasterxml.jackson.datatype:jackson-datatype-joda:${jackson2Version}")
testCompile("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:${jackson2Version}")
testCompile("com.fasterxml.jackson.module:jackson-module-kotlin:${jackson2Version}")
testCompile("com.fasterxml.jackson.datatype:jackson-datatype-joda:2.8.11")
testCompile("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.8.11")
testCompile("com.fasterxml.jackson.module:jackson-module-kotlin:2.8.11.1")
testCompile("com.squareup.okhttp3:mockwebserver:${okhttp3Version}")
testRuntime("com.sun.mail:javax.mail:${javamailVersion}")
}
}
@@ -836,7 +837,7 @@ project("spring-webmvc") {
exclude group: "org.springframework", module: "spring-context"
}
optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}")
optional("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${jackson2Version}")
optional("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.8.11")
optional("com.rometools:rome:${romeVersion}")
optional("javax.el:javax.el-api:2.2.5")
optional("org.apache.tiles:tiles-api:${tiles3Version}")
@@ -856,7 +857,7 @@ project("spring-webmvc") {
exclude group: "org.slf4j", module: "jcl-over-slf4j"
exclude group: "org.springframework", module: "spring-web"
}
optional('org.webjars:webjars-locator:0.32')
optional('org.webjars:webjars-locator:0.32-1')
testCompile("xmlunit:xmlunit:${xmlunitVersion}")
testCompile("dom4j:dom4j:1.6.1") {
exclude group: "xml-apis", module: "xml-apis"
@@ -876,13 +877,13 @@ project("spring-webmvc") {
testCompile("org.hibernate:hibernate-validator:${hibval4Version}")
testCompile("org.apache.httpcomponents:httpclient:${httpclientVersion}")
testCompile("commons-fileupload:commons-fileupload:${fileuploadVersion}")
testCompile("commons-io:commons-io:1.3")
testCompile("commons-io:commons-io:1.4")
testCompile("joda-time:joda-time:${jodaVersion}")
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
testCompile("org.jruby:jruby:${jrubyVersion}")
testCompile("org.python:jython-standalone:2.5.3")
testCompile("org.mozilla:rhino:1.7.7.1")
testCompile("org.webjars:underscorejs:1.8.3")
testCompile("org.mozilla:rhino:1.7.7.2")
testRuntime("org.jruby:jruby:${jrubyVersion}")
testRuntime("org.python:jython-standalone:2.5.3")
testRuntime("org.webjars:underscorejs:1.8.3")
}
}
@@ -937,8 +938,8 @@ project("spring-websocket") {
description = "Spring WebSocket"
dependencies {
compile(project(":spring-core"))
compile(project(":spring-context"))
compile(project(":spring-core"))
compile(project(":spring-web"))
optional(project(":spring-messaging"))
optional(project(":spring-webmvc"))
@@ -955,11 +956,11 @@ project("spring-websocket") {
optional("org.eclipse.jetty:jetty-webapp:${jettyVersion}") {
exclude group: "javax.servlet", module: "javax.servlet"
}
optional("org.eclipse.jetty.websocket:websocket-server:${jettyVersion}") {
optional("org.eclipse.jetty.websocket:websocket-server:${jetty94Version}") {
exclude group: "javax.servlet", module: "javax.servlet"
}
optional("org.eclipse.jetty.websocket:websocket-client:${jettyVersion}")
optional("org.eclipse.jetty:jetty-client:${jettyVersion}")
optional("org.eclipse.jetty.websocket:websocket-client:${jetty94Version}")
optional("org.eclipse.jetty:jetty-client:${jetty94Version}")
optional("io.undertow:undertow-core:${undertowVersion}")
optional("io.undertow:undertow-servlet:${undertowVersion}") {
exclude group: "org.jboss.spec.javax.servlet", module: "jboss-servlet-api_3.1_spec"
@@ -983,11 +984,12 @@ project("spring-test") {
dependencies {
compile(project(":spring-core"))
optional(project(":spring-aop"))
optional(project(":spring-beans"))
optional(project(":spring-context"))
optional(project(":spring-jdbc"))
optional(project(":spring-tx"))
optional(project(":spring-orm"))
optional(project(":spring-tx"))
optional(project(":spring-web"))
optional(project(":spring-webmvc"))
optional(project(":spring-webmvc-portlet"))
@@ -1008,11 +1010,11 @@ project("spring-test") {
optional("org.codehaus.groovy:groovy-all:${groovyVersion}")
optional("org.hamcrest:hamcrest-core:${hamcrestVersion}")
optional("xmlunit:xmlunit:${xmlunitVersion}")
optional("net.sourceforge.htmlunit:htmlunit:2.22")
optional("org.seleniumhq.selenium:htmlunit-driver:2.21")
optional("net.sourceforge.htmlunit:htmlunit:2.23")
optional("org.seleniumhq.selenium:htmlunit-driver:2.23.2")
optional("org.seleniumhq.selenium:selenium-java:2.53.1")
optional("org.skyscreamer:jsonassert:1.3.0")
optional("com.jayway.jsonpath:json-path:2.2.0")
optional("org.skyscreamer:jsonassert:1.4.0")
optional("com.jayway.jsonpath:json-path:2.3.0")
testCompile(project(":spring-context-support"))
testCompile(project(":spring-oxm"))
testCompile("javax.mail:javax.mail-api:${javamailVersion}")
@@ -1035,8 +1037,6 @@ project("spring-test") {
testCompile("org.apache.httpcomponents:httpclient:${httpclientVersion}")
testCompile("javax.cache:cache-api:1.0.0")
testRuntime("log4j:log4j:${log4jVersion}")
testRuntime("org.ehcache:ehcache:${ehcache3Version}")
testRuntime("org.terracotta:management-model:2.0.0")
}
task testNG(type: Test) {
@@ -1181,7 +1181,7 @@ configure(rootProject) {
// don't publish the default jar for the root project
configurations.archives.artifacts.clear()
dependencies { // for integration tests
dependencies { // for integration tests
testCompile(project(":spring-aop"))
testCompile(project(":spring-beans"))
testCompile(project(":spring-context"))
@@ -1230,11 +1230,11 @@ configure(rootProject) {
doFirst {
classpath = files(
// ensure Servlet 3.x and Hibernate 4.x have precedence on the javadoc
// Ensure Servlet 3.x and Hibernate 4.x have precedence on the javadoc
// classpath over their respective 2.5 and 3.x variants
project(":spring-webmvc").sourceSets.main.compileClasspath.files.find { it =~ "servlet-api" },
rootProject.sourceSets.test.compileClasspath.files.find { it =~ "hibernate-core" },
// ensure the javadoc process can resolve types compiled from .aj sources
// Ensure the javadoc process can resolve types compiled from .aj sources
project(":spring-aspects").sourceSets.main.output
)
classpath += files(subprojects.collect { it.sourceSets.main.compileClasspath })
@@ -1367,7 +1367,7 @@ configure(rootProject) {
task wrapper(type: Wrapper) {
description = "Generates gradlew[.bat] scripts"
gradleVersion = "2.13"
gradleVersion = "2.14.1"
doLast() {
def gradleOpts = "-XX:MaxMetaspaceSize=1024m -Xmx1024m"
+1 -1
View File
@@ -1 +1 @@
version=4.3.1.BUILD-SNAPSHOT
version=4.3.22.RELEASE
+2 -2
View File
@@ -29,8 +29,8 @@ def customizePom(pom, gradleProject) {
}
licenses {
license {
name "The Apache Software License, Version 2.0"
url "http://www.apache.org/licenses/LICENSE-2.0.txt"
name "Apache License, Version 2.0"
url "http://www.apache.org/licenses/LICENSE-2.0"
distribution "repo"
}
}
Binary file not shown.
+2 -2
View File
@@ -1,6 +1,6 @@
#Wed Jun 15 12:59:30 CEST 2016
#Wed Aug 17 21:21:18 CEST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-bin.zip
@@ -46,7 +46,7 @@ public interface MethodInterceptor extends Interceptor {
* after the invocation. Polite implementations would certainly
* like to invoke {@link Joinpoint#proceed()}.
* @param invocation the method invocation joinpoint
* @return the result of the call to {@link Joinpoint#proceed();
* @return the result of the call to {@link Joinpoint#proceed()};
* might be intercepted by the interceptor
* @throws Throwable if the interceptors or the target object
* throws an exception
@@ -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.
@@ -48,10 +48,11 @@ import java.lang.reflect.Method;
public interface MethodMatcher {
/**
* Perform static checking whether the given method matches. If this
* returns {@code false} or if the {@link #isRuntime()} method
* returns {@code false}, no runtime check (i.e. no.
* {@link #matches(java.lang.reflect.Method, Class, Object[])} call) will be made.
* Perform static checking whether the given method matches.
* <p>If this returns {@code false} or if the {@link #isRuntime()}
* method returns {@code false}, no runtime check (i.e. no
* {@link #matches(java.lang.reflect.Method, Class, Object[])} call)
* will be made.
* @param method the candidate method
* @param targetClass the target class (may be {@code null}, in which case
* the candidate class must be taken to be the method's declaring class)
@@ -1,5 +1,5 @@
/*<
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,9 +34,8 @@ public interface TargetSource extends TargetClassAware {
/**
* Return the type of targets returned by this {@link TargetSource}.
* <p>Can return {@code null}, although certain usages of a
* {@code TargetSource} might just work with a predetermined
* target class.
* <p>Can return {@code null}, although certain usages of a {@code TargetSource}
* might just work with a predetermined target class.
* @return the type of targets returned by this {@link TargetSource}
*/
@Override
@@ -44,9 +43,8 @@ public interface TargetSource extends TargetClassAware {
/**
* Will all calls to {@link #getTarget()} return the same object?
* <p>In that case, there will be no need to invoke
* {@link #releaseTarget(Object)}, and the AOP framework can cache
* the return value of {@link #getTarget()}.
* <p>In that case, there will be no need to invoke {@link #releaseTarget(Object)},
* and the AOP framework can cache the return value of {@link #getTarget()}.
* @return {@code true} if the target is immutable
* @see #getTarget
*/
@@ -55,14 +53,15 @@ public interface TargetSource extends TargetClassAware {
/**
* Return a target instance. Invoked immediately before the
* AOP framework calls the "target" of an AOP method invocation.
* @return the target object, which contains the joinpoint
* @return the target object which contains the joinpoint,
* or {@code null} if there is no actual target instance
* @throws Exception if the target object can't be resolved
*/
Object getTarget() throws Exception;
/**
* Release the given target object obtained from the
* {@link #getTarget()} method.
* {@link #getTarget()} method, if any.
* @param target object obtained from a call to {@link #getTarget()}
* @throws Exception if the object can't be released
*/
@@ -1,5 +1,5 @@
/*
* Copyright 2002-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.
@@ -103,8 +103,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
private final AspectInstanceFactory aspectInstanceFactory;
/**
* The name of the aspect (ref bean) in which this advice was defined (used
* when determining advice precedence so that we can determine
* The name of the aspect (ref bean) in which this advice was defined
* (used when determining advice precedence so that we can determine
* whether two pieces of advice come from the same aspect).
*/
private String aspectName;
@@ -118,13 +118,13 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
* This will be non-null if the creator of this advice object knows the argument names
* and sets them explicitly
*/
private String[] argumentNames = null;
private String[] argumentNames;
/** Non-null if after throwing advice binds the thrown value */
private String throwingName = null;
private String throwingName;
/** Non-null if after returning advice binds the return value */
private String returningName = null;
private String returningName;
private Class<?> discoveredReturningType = Object.class;
@@ -227,7 +227,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
}
/**
* Sets the <b>declaration order</b> of this advice within the aspect
* Set the declaration order of this advice within the aspect.
*/
public void setDeclarationOrder(int order) {
this.declarationOrder = order;
@@ -295,8 +295,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
}
catch (Throwable ex) {
throw new IllegalArgumentException("Returning name '" + name +
"' is neither a valid argument name nor the fully-qualified name of a Java type on the classpath. " +
"Root cause: " + ex);
"' is neither a valid argument name nor the fully-qualified " +
"name of a Java type on the classpath. Root cause: " + ex);
}
}
}
@@ -329,8 +329,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
}
catch (Throwable ex) {
throw new IllegalArgumentException("Throwing name '" + name +
"' is neither a valid argument name nor the fully-qualified name of a Java type on the classpath. " +
"Root cause: " + ex);
"' is neither a valid argument name nor the fully-qualified " +
"name of a Java type on the classpath. Root cause: " + ex);
}
}
}
@@ -366,7 +366,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
* to which argument name. There are multiple strategies for determining
* this binding, which are arranged in a ChainOfResponsibility.
*/
public synchronized final void calculateArgumentBindings() {
public final synchronized void calculateArgumentBindings() {
// The simple case... nothing to bind.
if (this.argumentsIntrospected || this.parameterTypes.length == 0) {
return;
@@ -374,10 +374,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
int numUnboundArgs = this.parameterTypes.length;
Class<?>[] parameterTypes = this.aspectJAdviceMethod.getParameterTypes();
if (maybeBindJoinPoint(parameterTypes[0]) || maybeBindProceedingJoinPoint(parameterTypes[0])) {
numUnboundArgs--;
}
else if (maybeBindJoinPointStaticPart(parameterTypes[0])) {
if (maybeBindJoinPoint(parameterTypes[0]) || maybeBindProceedingJoinPoint(parameterTypes[0]) ||
maybeBindJoinPointStaticPart(parameterTypes[0])) {
numUnboundArgs--;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -113,6 +113,7 @@ import org.springframework.util.StringUtils;
* returning {@code null} in the case that the parameter names cannot be discovered.
*
* @author Adrian Colyer
* @author Juergen Hoeller
* @since 2.0
*/
public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscoverer {
@@ -154,23 +155,17 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
}
/** The pointcut expression associated with the advice, as a simple String */
private String pointcutExpression;
private boolean raiseExceptions;
/**
* If the advice is afterReturning, and binds the return value, this is the parameter name used.
*/
/** If the advice is afterReturning, and binds the return value, this is the parameter name used */
private String returningName;
/**
* If the advice is afterThrowing, and binds the thrown value, this is the parameter name used.
*/
/** If the advice is afterThrowing, and binds the thrown value, this is the parameter name used */
private String throwingName;
/**
* The pointcut expression associated with the advice, as a simple String.
*/
private String pointcutExpression;
private Class<?>[] argumentTypes;
private String[] parameterNameBindings;
@@ -186,6 +181,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
this.pointcutExpression = pointcutExpression;
}
/**
* Indicate whether {@link IllegalArgumentException} and {@link AmbiguousBindingException}
* must be thrown as appropriate in the case of failing to deduce advice parameter names.
@@ -213,6 +209,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
this.throwingName = throwingName;
}
/**
* Deduce the parameter names for an advice method.
* <p>See the {@link AspectJAdviceParameterNameDiscoverer class level javadoc}
@@ -418,7 +415,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
String[] tokens = StringUtils.tokenizeToStringArray(this.pointcutExpression, " ");
for (int i = 0; i < tokens.length; i++) {
String toMatch = tokens[i];
int firstParenIndex = toMatch.indexOf("(");
int firstParenIndex = toMatch.indexOf('(');
if (firstParenIndex != -1) {
toMatch = toMatch.substring(0, firstParenIndex);
}
@@ -474,7 +471,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
* If the token starts meets Java identifier conventions, it's in.
*/
private String maybeExtractVariableName(String candidateToken) {
if (candidateToken == null || candidateToken.equals("")) {
if (!StringUtils.hasLength(candidateToken)) {
return null;
}
if (Character.isJavaIdentifierStart(candidateToken.charAt(0)) &&
@@ -578,7 +575,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
if (toMatch.startsWith("!")) {
toMatch = toMatch.substring(1);
}
int firstParenIndex = toMatch.indexOf("(");
int firstParenIndex = toMatch.indexOf('(');
if (firstParenIndex != -1) {
toMatch = toMatch.substring(0, firstParenIndex);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,7 +28,6 @@ import java.util.concurrent.ConcurrentHashMap;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.patterns.NamePattern;
import org.aspectj.weaver.reflect.ReflectionWorld.ReflectionWorldException;
import org.aspectj.weaver.reflect.ShadowMatchImpl;
@@ -187,13 +186,24 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
throw new IllegalStateException("Must set property 'expression' before attempting to match");
}
if (this.pointcutExpression == null) {
this.pointcutClassLoader = (this.beanFactory instanceof ConfigurableBeanFactory ?
((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader() :
ClassUtils.getDefaultClassLoader());
this.pointcutClassLoader = determinePointcutClassLoader();
this.pointcutExpression = buildPointcutExpression(this.pointcutClassLoader);
}
}
/**
* Determine the ClassLoader to use for pointcut evaluation.
*/
private ClassLoader determinePointcutClassLoader() {
if (this.beanFactory instanceof ConfigurableBeanFactory) {
return ((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader();
}
if (this.pointcutDeclarationScope != null) {
return this.pointcutDeclarationScope.getClassLoader();
}
return ClassUtils.getDefaultClassLoader();
}
/**
* Build the underlying AspectJ pointcut expression.
*/
@@ -258,7 +268,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
}
}
}
catch (BCException ex) {
catch (Throwable ex) {
logger.debug("PointcutExpression matching rejected target class", ex);
}
return false;
@@ -326,7 +336,6 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
}
catch (IllegalStateException ex) {
// No current invocation...
// TODO: Should we really proceed here?
if (logger.isDebugEnabled()) {
logger.debug("Could not access current invocation - matching with limited context: " + ex);
}
@@ -413,39 +422,46 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
shadowMatch = this.shadowMatchCache.get(targetMethod);
if (shadowMatch == null) {
try {
shadowMatch = this.pointcutExpression.matchesMethodExecution(methodToMatch);
}
catch (ReflectionWorldException ex) {
// Failed to introspect target method, probably because it has been loaded
// in a special ClassLoader. Let's try the declaring ClassLoader instead...
try {
fallbackExpression = getFallbackPointcutExpression(methodToMatch.getDeclaringClass());
if (fallbackExpression != null) {
shadowMatch = fallbackExpression.matchesMethodExecution(methodToMatch);
}
}
catch (ReflectionWorldException ex2) {
fallbackExpression = null;
}
}
if (shadowMatch == null && targetMethod != originalMethod) {
methodToMatch = originalMethod;
try {
shadowMatch = this.pointcutExpression.matchesMethodExecution(methodToMatch);
}
catch (ReflectionWorldException ex3) {
// Could neither introspect the target class nor the proxy class ->
// let's try the original method's declaring class before we give up...
catch (ReflectionWorldException ex) {
// Failed to introspect target method, probably because it has been loaded
// in a special ClassLoader. Let's try the declaring ClassLoader instead...
try {
fallbackExpression = getFallbackPointcutExpression(methodToMatch.getDeclaringClass());
if (fallbackExpression != null) {
shadowMatch = fallbackExpression.matchesMethodExecution(methodToMatch);
}
}
catch (ReflectionWorldException ex4) {
catch (ReflectionWorldException ex2) {
fallbackExpression = null;
}
}
if (shadowMatch == null && targetMethod != originalMethod) {
methodToMatch = originalMethod;
try {
shadowMatch = this.pointcutExpression.matchesMethodExecution(methodToMatch);
}
catch (ReflectionWorldException ex3) {
// Could neither introspect the target class nor the proxy class ->
// let's try the original method's declaring class before we give up...
try {
fallbackExpression = getFallbackPointcutExpression(methodToMatch.getDeclaringClass());
if (fallbackExpression != null) {
shadowMatch = fallbackExpression.matchesMethodExecution(methodToMatch);
}
}
catch (ReflectionWorldException ex4) {
fallbackExpression = null;
}
}
}
}
catch (Throwable ex) {
// Possibly AspectJ 1.8.10 encountering an invalid signature
logger.debug("PointcutExpression matching rejected target method", ex);
fallbackExpression = null;
}
if (shadowMatch == null) {
shadowMatch = new ShadowMatchImpl(org.aspectj.util.FuzzyBoolean.NO, null, null, null);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,8 @@ package org.springframework.aop.aspectj;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.AbstractGenericPointcutAdvisor;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
/**
* Spring AOP Advisor that can be used for any AspectJ pointcut expression.
@@ -26,16 +28,11 @@ import org.springframework.aop.support.AbstractGenericPointcutAdvisor;
* @since 2.0
*/
@SuppressWarnings("serial")
public class AspectJExpressionPointcutAdvisor extends AbstractGenericPointcutAdvisor {
public class AspectJExpressionPointcutAdvisor extends AbstractGenericPointcutAdvisor implements BeanFactoryAware {
private final AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
public void setExpression(String expression) {
this.pointcut.setExpression(expression);
}
@@ -52,12 +49,22 @@ public class AspectJExpressionPointcutAdvisor extends AbstractGenericPointcutAdv
return this.pointcut.getLocation();
}
public void setParameterTypes(Class<?>[] types) {
this.pointcut.setParameterTypes(types);
}
public void setParameterNames(String... names) {
this.pointcut.setParameterNames(names);
}
public void setParameterTypes(Class<?>... types) {
this.pointcut.setParameterTypes(types);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.pointcut.setBeanFactory(beanFactory);
}
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,7 +22,6 @@ import org.springframework.aop.Pointcut;
import org.springframework.aop.PointcutAdvisor;
import org.springframework.core.Ordered;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* AspectJPointcutAdvisor that adapts an {@link AbstractAspectJAdvice}
@@ -51,11 +50,11 @@ public class AspectJPointcutAdvisor implements PointcutAdvisor, Ordered {
this.pointcut = advice.buildSafePointcut();
}
public void setOrder(int order) {
this.order = order;
}
@Override
public boolean isPerInstance() {
return true;
@@ -91,12 +90,12 @@ public class AspectJPointcutAdvisor implements PointcutAdvisor, Ordered {
return false;
}
AspectJPointcutAdvisor otherAdvisor = (AspectJPointcutAdvisor) other;
return (ObjectUtils.nullSafeEquals(this.advice, otherAdvisor.advice));
return this.advice.equals(otherAdvisor.advice);
}
@Override
public int hashCode() {
return AspectJPointcutAdvisor.class.hashCode();
return AspectJPointcutAdvisor.class.hashCode() * 29 + this.advice.hashCode();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 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.
@@ -20,6 +20,7 @@ import org.aopalliance.aop.Advice;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.IntroductionAdvisor;
import org.springframework.aop.IntroductionInterceptor;
import org.springframework.aop.support.ClassFilters;
import org.springframework.aop.support.DelegatePerTargetObjectIntroductionInterceptor;
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
@@ -34,12 +35,12 @@ import org.springframework.aop.support.DelegatingIntroductionInterceptor;
*/
public class DeclareParentsAdvisor implements IntroductionAdvisor {
private final Advice advice;
private final Class<?> introducedInterface;
private final ClassFilter typePatternClassFilter;
private final Advice advice;
/**
* Create a new advisor for this DeclareParents field.
@@ -48,8 +49,8 @@ public class DeclareParentsAdvisor implements IntroductionAdvisor {
* @param defaultImpl the default implementation class
*/
public DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, Class<?> defaultImpl) {
this(interfaceType, typePattern, defaultImpl,
new DelegatePerTargetObjectIntroductionInterceptor(defaultImpl, interfaceType));
this(interfaceType, typePattern,
new DelegatePerTargetObjectIntroductionInterceptor(defaultImpl, interfaceType));
}
/**
@@ -59,8 +60,7 @@ public class DeclareParentsAdvisor implements IntroductionAdvisor {
* @param delegateRef the delegate implementation object
*/
public DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, Object delegateRef) {
this(interfaceType, typePattern, delegateRef.getClass(),
new DelegatingIntroductionInterceptor(delegateRef));
this(interfaceType, typePattern, new DelegatingIntroductionInterceptor(delegateRef));
}
/**
@@ -68,23 +68,21 @@ public class DeclareParentsAdvisor implements IntroductionAdvisor {
* (cannot use method such as init() to share common code, due the use of final fields)
* @param interfaceType static field defining the introduction
* @param typePattern type pattern the introduction is restricted to
* @param implementationClass implementation class
* @param advice delegation advice
* @param interceptor the delegation advice as {@link IntroductionInterceptor}
*/
private DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, Class<?> implementationClass, Advice advice) {
private DeclareParentsAdvisor(Class<?> interfaceType, String typePattern, IntroductionInterceptor interceptor) {
this.advice = interceptor;
this.introducedInterface = interfaceType;
ClassFilter typePatternFilter = new TypePatternClassFilter(typePattern);
// Excludes methods implemented.
ClassFilter typePatternFilter = new TypePatternClassFilter(typePattern);
ClassFilter exclusion = new ClassFilter() {
@Override
public boolean matches(Class<?> clazz) {
return !(introducedInterface.isAssignableFrom(clazz));
return !introducedInterface.isAssignableFrom(clazz);
}
};
this.typePatternClassFilter = ClassFilters.intersection(typePatternFilter, exclusion);
this.advice = advice;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-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.
@@ -32,17 +32,15 @@ import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.util.Assert;
/**
* Implementation of AspectJ ProceedingJoinPoint interface
* wrapping an AOP Alliance MethodInvocation.
* An implementation of the AspectJ {@link ProceedingJoinPoint} interface
* wrapping an AOP Alliance {@link org.aopalliance.intercept.MethodInvocation}.
*
* <p><b>Note</b>: the {@code getThis()} method returns the current Spring AOP proxy.
* <p><b>Note</b>: The {@code getThis()} method returns the current Spring AOP proxy.
* The {@code getTarget()} method returns the current Spring AOP target (which may be
* {@code null} if there is no target), and is a plain POJO without any advice.
* <b>If you want to call the object and have the advice take effect, use
* {@code getThis()}.</b> A common example is casting the object to an
* introduced interface in the implementation of an introduction.
*
* <p>Of course there is no such distinction between target and proxy in AspectJ.
* {@code null} if there is no target instance) as a plain POJO without any advice.
* <b>If you want to call the object and have the advice take effect, use {@code getThis()}.</b>
* A common example is casting the object to an introduced interface in the implementation of
* an introduction. There is no such distinction between target and proxy in AspectJ itself.
*
* @author Rod Johnson
* @author Juergen Hoeller
@@ -56,7 +54,7 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
private final ProxyMethodInvocation methodInvocation;
private Object[] defensiveCopyOfArgs;
private Object[] args;
/** Lazily initialized signature object */
private Signature signature;
@@ -75,6 +73,7 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
this.methodInvocation = methodInvocation;
}
@Override
public void set$AroundClosure(AroundClosure aroundClosure) {
throw new UnsupportedOperationException();
@@ -115,12 +114,10 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
@Override
public Object[] getArgs() {
if (this.defensiveCopyOfArgs == null) {
Object[] argsSource = this.methodInvocation.getArguments();
this.defensiveCopyOfArgs = new Object[argsSource.length];
System.arraycopy(argsSource, 0, this.defensiveCopyOfArgs, 0, argsSource.length);
if (this.args == null) {
this.args = this.methodInvocation.getArguments().clone();
}
return this.defensiveCopyOfArgs;
return this.args;
}
@Override
@@ -128,7 +125,7 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
if (this.signature == null) {
this.signature = new MethodSignatureImpl();
}
return signature;
return this.signature;
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 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,6 +41,7 @@ public class SimpleAspectInstanceFactory implements AspectInstanceFactory {
this.aspectClass = aspectClass;
}
/**
* Return the specified aspect class (never {@code null}).
*/
@@ -48,17 +49,18 @@ public class SimpleAspectInstanceFactory implements AspectInstanceFactory {
return this.aspectClass;
}
@Override
public final Object getAspectInstance() {
try {
return this.aspectClass.newInstance();
}
catch (InstantiationException ex) {
throw new AopConfigException("Unable to instantiate aspect class [" + this.aspectClass.getName() + "]", ex);
throw new AopConfigException(
"Unable to instantiate aspect class: " + this.aspectClass.getName(), ex);
}
catch (IllegalAccessException ex) {
throw new AopConfigException("Cannot access element class [" + this.aspectClass.getName() + "]", ex);
throw new AopConfigException(
"Could not access aspect constructor: " + this.aspectClass.getName(), ex);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 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,6 +27,7 @@ import org.springframework.util.StringUtils;
* Spring AOP {@link ClassFilter} implementation using AspectJ type matching.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 2.0
*/
public class TypePatternClassFilter implements ClassFilter {
@@ -76,17 +77,21 @@ public class TypePatternClassFilter implements ClassFilter {
* or is recognized as invalid
*/
public void setTypePattern(String typePattern) {
Assert.notNull(typePattern);
Assert.notNull(typePattern, "Type pattern must not be null");
this.typePattern = typePattern;
this.aspectJTypePatternMatcher =
PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution().
parseTypePattern(replaceBooleanOperators(typePattern));
}
/**
* Return the AspectJ type pattern to match.
*/
public String getTypePattern() {
return typePattern;
return this.typePattern;
}
/**
* Should the pointcut apply to the given interface or target class?
* @param clazz candidate target class
@@ -95,9 +100,7 @@ public class TypePatternClassFilter implements ClassFilter {
*/
@Override
public boolean matches(Class<?> clazz) {
if (this.aspectJTypePatternMatcher == null) {
throw new IllegalStateException("No 'typePattern' has been set via ctor/setter.");
}
Assert.state(this.aspectJTypePatternMatcher != null, "No type pattern has been set");
return this.aspectJTypePatternMatcher.matches(clazz);
}
@@ -108,9 +111,8 @@ public class TypePatternClassFilter implements ClassFilter {
* <p>This method converts back to {@code &&} for the AspectJ pointcut parser.
*/
private String replaceBooleanOperators(String pcExpr) {
pcExpr = StringUtils.replace(pcExpr," and "," && ");
pcExpr = StringUtils.replace(pcExpr, " or ", " || ");
pcExpr = StringUtils.replace(pcExpr, " not ", " ! ");
return pcExpr;
String result = StringUtils.replace(pcExpr," and "," && ");
result = StringUtils.replace(result, " or ", " || ");
return StringUtils.replace(result, " not ", " ! ");
}
}
@@ -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.
@@ -38,7 +38,6 @@ import org.aspectj.lang.reflect.AjType;
import org.aspectj.lang.reflect.AjTypeSystem;
import org.aspectj.lang.reflect.PerClauseKind;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.framework.AopConfigException;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.annotation.AnnotationUtils;
@@ -60,6 +59,9 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
private static final String AJC_MAGIC = "ajc$";
private static final Class<?>[] ASPECTJ_ANNOTATION_CLASSES = new Class<?>[] {
Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class};
/** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass());
@@ -121,59 +123,14 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
}
}
/**
* The pointcut and advice annotations both have an "argNames" member which contains a
* comma-separated list of the argument names. We use this (if non-empty) to build the
* formal parameters for the pointcut.
*/
protected AspectJExpressionPointcut createPointcutExpression(
Method annotatedMethod, Class<?> declarationScope, String[] pointcutParameterNames) {
Class<?> [] pointcutParameterTypes = new Class<?>[0];
if (pointcutParameterNames != null) {
pointcutParameterTypes = extractPointcutParameterTypes(pointcutParameterNames,annotatedMethod);
}
AspectJExpressionPointcut ajexp =
new AspectJExpressionPointcut(declarationScope,pointcutParameterNames,pointcutParameterTypes);
ajexp.setLocation(annotatedMethod.toString());
return ajexp;
}
/**
* Create the pointcut parameters needed by aspectj based on the given argument names
* and the argument types that are available from the adviceMethod. Needs to take into
* account (ignore) any JoinPoint based arguments as these are not pointcut context but
* rather part of the advice execution context (thisJoinPoint, thisJoinPointStaticPart)
*/
private Class<?>[] extractPointcutParameterTypes(String[] argNames, Method adviceMethod) {
Class<?>[] ret = new Class<?>[argNames.length];
Class<?>[] paramTypes = adviceMethod.getParameterTypes();
if (argNames.length > paramTypes.length) {
throw new IllegalStateException("Expecting at least " + argNames.length +
" arguments in the advice declaration, but only found " + paramTypes.length);
}
// Make the simplifying assumption for now that all of the JoinPoint based arguments
// come first in the advice declaration.
int typeOffset = paramTypes.length - argNames.length;
for (int i = 0; i < ret.length; i++) {
ret[i] = paramTypes[i + typeOffset];
}
return ret;
}
/**
* Find and return the first AspectJ annotation on the given method
* (there <i>should</i> only be one anyway...)
* (there <i>should</i> only be one anyway...).
*/
@SuppressWarnings("unchecked")
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
Class<?>[] classesToLookFor = new Class<?>[] {
Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
for (Class<?> c : classesToLookFor) {
AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) c);
for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {
AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz);
if (foundAnnotation != null) {
return foundAnnotation;
}
@@ -192,14 +149,13 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
}
/**
* Enum for AspectJ annotation types.
* @see AspectJAnnotation#getAnnotationType()
*/
protected enum AspectJAnnotationType {
AtPointcut,
AtBefore,
AtAfter,
AtAfterReturning,
AtAfterThrowing,
AtAround
AtPointcut, AtAround, AtBefore, AtAfter, AtAfterReturning, AtAfterThrowing
}
@@ -209,18 +165,18 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
*/
protected static class AspectJAnnotation<A extends Annotation> {
private static final String[] EXPRESSION_PROPERTIES = new String[] {"value", "pointcut"};
private static final String[] EXPRESSION_ATTRIBUTES = new String[] {"pointcut", "value"};
private static Map<Class<?>, AspectJAnnotationType> annotationTypes =
new HashMap<Class<?>, AspectJAnnotationType>();
private static Map<Class<?>, AspectJAnnotationType> annotationTypeMap =
new HashMap<Class<?>, AspectJAnnotationType>(8);
static {
annotationTypes.put(Pointcut.class,AspectJAnnotationType.AtPointcut);
annotationTypes.put(After.class,AspectJAnnotationType.AtAfter);
annotationTypes.put(AfterReturning.class,AspectJAnnotationType.AtAfterReturning);
annotationTypes.put(AfterThrowing.class,AspectJAnnotationType.AtAfterThrowing);
annotationTypes.put(Around.class,AspectJAnnotationType.AtAround);
annotationTypes.put(Before.class,AspectJAnnotationType.AtBefore);
annotationTypeMap.put(Pointcut.class, AspectJAnnotationType.AtPointcut);
annotationTypeMap.put(Around.class, AspectJAnnotationType.AtAround);
annotationTypeMap.put(Before.class, AspectJAnnotationType.AtBefore);
annotationTypeMap.put(After.class, AspectJAnnotationType.AtAfter);
annotationTypeMap.put(AfterReturning.class, AspectJAnnotationType.AtAfterReturning);
annotationTypeMap.put(AfterThrowing.class, AspectJAnnotationType.AtAfterThrowing);
}
private final A annotation;
@@ -234,44 +190,31 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
public AspectJAnnotation(A annotation) {
this.annotation = annotation;
this.annotationType = determineAnnotationType(annotation);
// We know these methods exist with the same name on each object,
// but need to invoke them reflectively as there isn't a common interface.
try {
this.pointcutExpression = resolveExpression(annotation);
this.argumentNames = (String) annotation.getClass().getMethod("argNames").invoke(annotation);
this.argumentNames = (String) AnnotationUtils.getValue(annotation, "argNames");
}
catch (Exception ex) {
throw new IllegalArgumentException(annotation + " cannot be an AspectJ annotation", ex);
throw new IllegalArgumentException(annotation + " is not a valid AspectJ annotation", ex);
}
}
private AspectJAnnotationType determineAnnotationType(A annotation) {
for (Class<?> type : annotationTypes.keySet()) {
if (type.isInstance(annotation)) {
return annotationTypes.get(type);
}
AspectJAnnotationType type = annotationTypeMap.get(annotation.annotationType());
if (type != null) {
return type;
}
throw new IllegalStateException("Unknown annotation type: " + annotation.toString());
throw new IllegalStateException("Unknown annotation type: " + annotation);
}
private String resolveExpression(A annotation) throws Exception {
String expression = null;
for (String methodName : EXPRESSION_PROPERTIES) {
Method method;
try {
method = annotation.getClass().getDeclaredMethod(methodName);
}
catch (NoSuchMethodException ex) {
method = null;
}
if (method != null) {
String candidate = (String) method.invoke(annotation);
if (StringUtils.hasText(candidate)) {
expression = candidate;
}
private String resolveExpression(A annotation) {
for (String attributeName : EXPRESSION_ATTRIBUTES) {
String candidate = (String) AnnotationUtils.getValue(annotation, attributeName);
if (StringUtils.hasText(candidate)) {
return candidate;
}
}
return expression;
throw new IllegalStateException("Failed to resolve expression: " + annotation);
}
public AspectJAnnotationType getAnnotationType() {
@@ -312,11 +255,11 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
if (annotation == null) {
return null;
}
StringTokenizer strTok = new StringTokenizer(annotation.getArgumentNames(), ",");
if (strTok.countTokens() > 0) {
String[] names = new String[strTok.countTokens()];
StringTokenizer nameTokens = new StringTokenizer(annotation.getArgumentNames(), ",");
if (nameTokens.countTokens() > 0) {
String[] names = new String[nameTokens.countTokens()];
for (int i = 0; i < names.length; i++) {
names[i] = strTok.nextToken();
names[i] = nameTokens.nextToken();
}
return names;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -50,7 +50,7 @@ public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorA
private List<Pattern> includePatterns;
private AspectJAdvisorFactory aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory();
private AspectJAdvisorFactory aspectJAdvisorFactory;
private BeanFactoryAspectJAdvisorsBuilder aspectJAdvisorsBuilder;
@@ -74,6 +74,9 @@ public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorA
@Override
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
if (this.aspectJAdvisorFactory == null) {
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
}
this.aspectJAdvisorsBuilder =
new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}
@@ -130,6 +133,7 @@ public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorA
public BeanFactoryAspectJAdvisorsBuilderAdapter(
ListableBeanFactory beanFactory, AspectJAdvisorFactory advisorFactory) {
super(beanFactory, advisorFactory);
}
@@ -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.
@@ -16,9 +16,9 @@
package org.springframework.aop.aspectj.annotation;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.aspectj.lang.reflect.PerClauseKind;
@@ -50,7 +50,7 @@ import org.springframework.util.ClassUtils;
public class AspectJProxyFactory extends ProxyCreatorSupport {
/** Cache for singleton aspect instances */
private static final Map<Class<?>, Object> aspectCache = new HashMap<Class<?>, Object>();
private static final Map<Class<?>, Object> aspectCache = new ConcurrentHashMap<Class<?>, Object>();
private final AspectJAdvisorFactory aspectFactory = new ReflectiveAspectJAdvisorFactory();
@@ -144,7 +144,7 @@ public class AspectJProxyFactory extends ProxyCreatorSupport {
private MetadataAwareAspectInstanceFactory createAspectInstanceFactory(
AspectMetadata am, Class<?> aspectClass, String aspectName) {
MetadataAwareAspectInstanceFactory instanceFactory = null;
MetadataAwareAspectInstanceFactory instanceFactory;
if (am.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
// Create a shared aspect instance.
Object instance = getSingletonAspectInstance(aspectClass);
@@ -162,23 +162,29 @@ public class AspectJProxyFactory extends ProxyCreatorSupport {
* is created if one cannot be found in the instance cache.
*/
private Object getSingletonAspectInstance(Class<?> aspectClass) {
synchronized (aspectCache) {
Object instance = aspectCache.get(aspectClass);
if (instance != null) {
return instance;
}
try {
instance = aspectClass.newInstance();
aspectCache.put(aspectClass, instance);
return instance;
}
catch (InstantiationException ex) {
throw new AopConfigException("Unable to instantiate aspect class [" + aspectClass.getName() + "]", ex);
}
catch (IllegalAccessException ex) {
throw new AopConfigException("Cannot access aspect class [" + aspectClass.getName() + "]", ex);
// Quick check without a lock...
Object instance = aspectCache.get(aspectClass);
if (instance == null) {
synchronized (aspectCache) {
// To be safe, check within full lock now...
instance = aspectCache.get(aspectClass);
if (instance == null) {
try {
instance = aspectClass.newInstance();
aspectCache.put(aspectClass, instance);
}
catch (InstantiationException ex) {
throw new AopConfigException(
"Unable to instantiate aspect class: " + aspectClass.getName(), ex);
}
catch (IllegalAccessException ex) {
throw new AopConfigException(
"Could not access aspect constructor: " + aspectClass.getName(), ex);
}
}
}
}
return instance;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,9 +35,8 @@ import org.springframework.aop.support.ComposablePointcut;
* Metadata for an AspectJ aspect class, with an additional Spring AOP pointcut
* for the per clause.
*
* <p>Uses AspectJ 5 AJType reflection API, so is only supported on Java 5.
* Enables us to work with different AspectJ instantiation models such as
* "singleton", "pertarget" and "perthis".
* <p>Uses AspectJ 5 AJType reflection API, enabling us to work with different
* AspectJ instantiation models such as "singleton", "pertarget" and "perthis".
*
* @author Rod Johnson
* @author Juergen Hoeller
@@ -102,20 +101,22 @@ public class AspectMetadata implements Serializable {
this.ajType = ajType;
switch (this.ajType.getPerClause().getKind()) {
case SINGLETON :
case SINGLETON:
this.perClausePointcut = Pointcut.TRUE;
return;
case PERTARGET : case PERTHIS :
case PERTARGET:
case PERTHIS:
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut();
ajexp.setLocation("@Aspect annotation on " + aspectClass.getName());
ajexp.setLocation(aspectClass.getName());
ajexp.setExpression(findPerClause(aspectClass));
ajexp.setPointcutDeclarationScope(aspectClass);
this.perClausePointcut = ajexp;
return;
case PERTYPEWITHIN :
case PERTYPEWITHIN:
// Works with a type pattern
this.perClausePointcut = new ComposablePointcut(new TypePatternClassFilter(findPerClause(aspectClass)));
return;
default :
default:
throw new AopConfigException(
"PerClause " + ajType.getPerClause().getKind() + " not supported by Spring AOP for " + aspectClass);
}
@@ -125,10 +126,8 @@ public class AspectMetadata implements Serializable {
* Extract contents from String of form {@code pertarget(contents)}.
*/
private String findPerClause(Class<?> aspectClass) {
// TODO when AspectJ provides this, we can remove this hack. Hence we don't
// bother to make it elegant. Or efficient. Or robust :-)
String str = aspectClass.getAnnotation(Aspect.class).value();
str = str.substring(str.indexOf("(") + 1);
str = str.substring(str.indexOf('(') + 1);
str = str.substring(0, str.length() - 1);
return str;
}
@@ -149,7 +148,7 @@ public class AspectMetadata implements Serializable {
}
/**
* Return the aspect class.
* Return the aspect name.
*/
public String getAspectName() {
return this.aspectName;
@@ -97,8 +97,19 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
@Override
public Object getAspectCreationMutex() {
return (this.beanFactory instanceof ConfigurableBeanFactory ?
((ConfigurableBeanFactory) this.beanFactory).getSingletonMutex() : this);
if (this.beanFactory != null) {
if (this.beanFactory.isSingleton(name)) {
// Rely on singleton semantics provided by the factory -> no local lock.
return null;
}
else if (this.beanFactory instanceof ConfigurableBeanFactory) {
// No singleton guarantees from the factory -> let's lock locally but
// reuse the factory's singleton lock, just in case a lazy dependency
// of our advice bean happens to trigger the singleton lock implicitly...
return ((ConfigurableBeanFactory) this.beanFactory).getSingletonMutex();
}
}
return this;
}
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,10 +17,10 @@
package org.springframework.aop.aspectj.annotation;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.aspectj.lang.reflect.PerClauseKind;
@@ -43,12 +43,12 @@ public class BeanFactoryAspectJAdvisorsBuilder {
private final AspectJAdvisorFactory advisorFactory;
private List<String> aspectBeanNames;
private volatile List<String> aspectBeanNames;
private final Map<String, List<Advisor>> advisorsCache = new HashMap<String, List<Advisor>>();
private final Map<String, List<Advisor>> advisorsCache = new ConcurrentHashMap<String, List<Advisor>>();
private final Map<String, MetadataAwareAspectInstanceFactory> aspectFactoryCache =
new HashMap<String, MetadataAwareAspectInstanceFactory>();
new ConcurrentHashMap<String, MetadataAwareAspectInstanceFactory>();
/**
@@ -56,7 +56,7 @@ public class BeanFactoryAspectJAdvisorsBuilder {
* @param beanFactory the ListableBeanFactory to scan
*/
public BeanFactoryAspectJAdvisorsBuilder(ListableBeanFactory beanFactory) {
this(beanFactory, new ReflectiveAspectJAdvisorFactory());
this(beanFactory, new ReflectiveAspectJAdvisorFactory(beanFactory));
}
/**
@@ -80,56 +80,57 @@ public class BeanFactoryAspectJAdvisorsBuilder {
* @see #isEligibleBean
*/
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = null;
List<String> aspectNames = this.aspectBeanNames;
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new LinkedList<Advisor>();
aspectNames = new LinkedList<String>();
String[] beanNames =
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
// We must be careful not to instantiate beans eagerly as in this
// case they would be cached by the Spring container but would not
// have been weaved
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new LinkedList<Advisor>();
aspectNames = new LinkedList<String>();
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
// We must be careful not to instantiate beans eagerly as in this case they
// would be cached by the Spring container but would not have been weaved.
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
else {
// Per target or per this.
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" + beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
advisors.addAll(classAdvisors);
}
else {
// Per target or per this.
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" + beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
@@ -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.
@@ -109,14 +109,40 @@ class InstantiationModelAwarePointcutAdvisorImpl
/**
* The pointcut for Spring AOP to use. Actual behaviour of the pointcut will change
* depending on the state of the advice.
* The pointcut for Spring AOP to use.
* Actual behaviour of the pointcut will change depending on the state of the advice.
*/
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
@Override
public boolean isLazy() {
return this.lazy;
}
@Override
public synchronized boolean isAdviceInstantiated() {
return (this.instantiatedAdvice != null);
}
/**
* Lazily instantiate advice if necessary.
*/
@Override
public synchronized Advice getAdvice() {
if (this.instantiatedAdvice == null) {
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
return this.instantiatedAdvice;
}
private Advice instantiateAdvice(AspectJExpressionPointcut pcut) {
return this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
}
/**
* This is only of interest for Spring AOP: AspectJ instantiation semantics
* are much richer. In AspectJ terminology, all a return of {@code true}
@@ -134,33 +160,6 @@ class InstantiationModelAwarePointcutAdvisorImpl
return this.aspectInstanceFactory.getAspectMetadata();
}
/**
* Lazily instantiate advice if necessary.
*/
@Override
public synchronized Advice getAdvice() {
if (this.instantiatedAdvice == null) {
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
return this.instantiatedAdvice;
}
@Override
public boolean isLazy() {
return this.lazy;
}
@Override
public synchronized boolean isAdviceInstantiated() {
return (this.instantiatedAdvice != null);
}
private Advice instantiateAdvice(AspectJExpressionPointcut pcut) {
return this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
}
public MetadataAwareAspectInstanceFactory getAspectInstanceFactory() {
return this.aspectInstanceFactory;
}
@@ -213,33 +212,26 @@ class InstantiationModelAwarePointcutAdvisorImpl
}
else {
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
case AtAround:
this.isBeforeAdvice = false;
this.isAfterAdvice = false;
break;
case AtBefore:
this.isBeforeAdvice = true;
this.isAfterAdvice = false;
break;
case AtAfter:
case AtAfterReturning:
case AtAfterThrowing:
this.isBeforeAdvice = false;
this.isAfterAdvice = true;
this.isBeforeAdvice = false;
break;
case AtAround:
case AtPointcut:
this.isAfterAdvice = false;
this.isBeforeAdvice = false;
break;
case AtBefore:
this.isAfterAdvice = false;
this.isBeforeAdvice = true;
}
}
}
@Override
public String toString() {
return "InstantiationModelAwarePointcutAdvisor: expression [" + getDeclaredPointcut().getExpression() +
"]; advice method [" + this.aspectJAdviceMethod + "]; perClauseKind=" +
this.aspectInstanceFactory.getAspectMetadata().getAjType().getPerClause().getKind();
}
private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
inputStream.defaultReadObject();
try {
@@ -250,11 +242,18 @@ class InstantiationModelAwarePointcutAdvisorImpl
}
}
@Override
public String toString() {
return "InstantiationModelAwarePointcutAdvisor: expression [" + getDeclaredPointcut().getExpression() +
"]; advice method [" + this.aspectJAdviceMethod + "]; perClauseKind=" +
this.aspectInstanceFactory.getAspectMetadata().getAjType().getPerClause().getKind();
}
/**
* Pointcut implementation that changes its behaviour when the advice is instantiated.
* Note that this is a <i>dynamic</i> pointcut. Otherwise it might
* be optimized out if it does not at first match statically.
* Note that this is a <i>dynamic</i> pointcut; otherwise it might be optimized out
* if it does not at first match statically.
*/
private class PerTargetInstantiationModelPointcut extends DynamicMethodMatcherPointcut {
@@ -264,8 +263,9 @@ class InstantiationModelAwarePointcutAdvisorImpl
private LazySingletonAspectInstanceFactoryDecorator aspectInstanceFactory;
private PerTargetInstantiationModelPointcut(AspectJExpressionPointcut declaredPointcut,
public PerTargetInstantiationModelPointcut(AspectJExpressionPointcut declaredPointcut,
Pointcut preInstantiationPointcut, MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
this.declaredPointcut = declaredPointcut;
this.preInstantiationPointcut = preInstantiationPointcut;
if (aspectInstanceFactory instanceof LazySingletonAspectInstanceFactoryDecorator) {
@@ -275,7 +275,8 @@ class InstantiationModelAwarePointcutAdvisorImpl
@Override
public boolean matches(Method method, Class<?> targetClass) {
// We're either instantiated and matching on declared pointcut, or uninstantiated matching on either pointcut
// We're either instantiated and matching on declared pointcut,
// or uninstantiated matching on either pointcut...
return (isAspectMaterialized() && this.declaredPointcut.matches(method, targetClass)) ||
this.preInstantiationPointcut.getMethodMatcher().matches(method, targetClass);
}
@@ -48,9 +48,15 @@ public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwar
@Override
public Object getAspectInstance() {
if (this.materialized == null) {
synchronized (this.maaif.getAspectCreationMutex()) {
if (this.materialized == null) {
this.materialized = this.maaif.getAspectInstance();
Object mutex = this.maaif.getAspectCreationMutex();
if (mutex == null) {
this.materialized = this.maaif.getAspectInstance();
}
else {
synchronized (mutex) {
if (this.materialized == null) {
this.materialized = this.maaif.getAspectInstance();
}
}
}
}
@@ -41,7 +41,7 @@ public interface MetadataAwareAspectInstanceFactory extends AspectInstanceFactor
/**
* Return the best possible creation mutex for this factory.
* @return the mutex object (never {@code null})
* @return the mutex object (may be {@code null} for no mutex to use)
* @since 4.3
*/
Object getAspectCreationMutex();
@@ -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.
@@ -20,9 +20,9 @@ import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import org.aopalliance.aop.Advice;
@@ -46,6 +46,7 @@ import org.springframework.aop.aspectj.AspectJMethodBeforeAdvice;
import org.springframework.aop.aspectj.DeclareParentsAdvisor;
import org.springframework.aop.framework.AopConfigException;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConvertingComparator;
@@ -95,6 +96,30 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
}
private final BeanFactory beanFactory;
/**
* Create a new {@code ReflectiveAspectJAdvisorFactory}.
*/
public ReflectiveAspectJAdvisorFactory() {
this(null);
}
/**
* Create a new {@code ReflectiveAspectJAdvisorFactory}, propagating the given
* {@link BeanFactory} to the created {@link AspectJExpressionPointcut} instances,
* for bean pointcut handling as well as consistent {@link ClassLoader} resolution.
* @param beanFactory the BeanFactory to propagate (may be {@code null}}
* @since 4.3.6
* @see AspectJExpressionPointcut#setBeanFactory
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory#getBeanClassLoader()
*/
public ReflectiveAspectJAdvisorFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
@@ -106,7 +131,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new LinkedList<Advisor>();
List<Advisor> advisors = new ArrayList<Advisor>();
for (Method method : getAdvisorMethods(aspectClass)) {
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
@@ -132,7 +157,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
}
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
final List<Method> methods = new LinkedList<Method>();
final List<Method> methods = new ArrayList<Method>();
ReflectionUtils.doWithMethods(aspectClass, new ReflectionUtils.MethodCallback() {
@Override
public void doWith(Method method) throws IllegalArgumentException {
@@ -151,7 +176,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
* for the given introduction field.
* <p>Resulting Advisors will need to be evaluated for targets.
* @param introductionField the field to introspect
* @return {@code null} if not an Advisor
* @return the Advisor instance, or {@code null} if not an Advisor
*/
private Advisor getDeclareParentsAdvisor(Field introductionField) {
DeclareParents declareParents = introductionField.getAnnotation(DeclareParents.class);
@@ -161,9 +186,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
}
if (DeclareParents.class == declareParents.defaultImpl()) {
// This is what comes back if it wasn't set. This seems bizarre...
// TODO this restriction possibly should be relaxed
throw new IllegalStateException("defaultImpl must be set on DeclareParents");
throw new IllegalStateException("'defaultImpl' attribute must be set on DeclareParents");
}
return new DeclareParentsAdvisor(
@@ -197,6 +220,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
AspectJExpressionPointcut ajexp =
new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
ajexp.setBeanFactory(this.beanFactory);
return ajexp;
}
@@ -229,6 +253,15 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
AbstractAspectJAdvice springAdvice;
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
@@ -253,15 +286,6 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
@@ -275,6 +299,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();
return springAdvice;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -71,7 +71,7 @@ public abstract class AbstractInterceptorDrivenBeanDefinitionDecorator implement
BeanDefinition interceptorDefinition = createInterceptorDefinition(node);
// generate name and register the interceptor
String interceptorName = existingBeanName + "." + getInterceptorNameSuffix(interceptorDefinition);
String interceptorName = existingBeanName + '.' + getInterceptorNameSuffix(interceptorDefinition);
BeanDefinitionReaderUtils.registerBeanDefinition(
new BeanDefinitionHolder(interceptorDefinition, interceptorName), registry);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-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.
@@ -31,11 +31,10 @@ import org.springframework.util.Assert;
/**
* Utility class for handling registration of AOP auto-proxy creators.
*
* <p>Only a single auto-proxy creator can be registered yet multiple concrete
* implementations are available. Therefore this class wraps a simple escalation
* protocol, allowing classes to request a particular auto-proxy creator and know
* that class, {@code or a subclass thereof}, will eventually be resident
* in the application context.
* <p>Only a single auto-proxy creator should be registered yet multiple concrete
* implementations are available. This class provides a simple escalation protocol,
* allowing a caller to request a particular auto-proxy creator and know that creator,
* <i>or a more capable variant thereof</i>, will be registered as a post-processor.
*
* @author Rob Harrop
* @author Juergen Hoeller
@@ -54,12 +53,10 @@ public abstract class AopConfigUtils {
/**
* Stores the auto proxy creator classes in escalation order.
*/
private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<Class<?>>();
private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<Class<?>>(3);
/**
* Setup the escalation list.
*/
static {
// Set up the escalation list...
APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
@@ -107,6 +104,7 @@ public abstract class AopConfigUtils {
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
@@ -118,6 +116,7 @@ public abstract class AopConfigUtils {
}
return null;
}
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
@@ -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.
@@ -27,11 +27,11 @@ import org.springframework.beans.factory.xml.ParserContext;
* Utility class for handling registration of auto-proxy creators used internally
* by the '{@code aop}' namespace tags.
*
* <p>Only a single auto-proxy creator can be registered and multiple tags may wish
* to register different concrete implementations. As such this class delegates to
* {@link AopConfigUtils} which wraps a simple escalation protocol. Therefore classes
* may request a particular auto-proxy creator and know that class, <i>or a subclass
* thereof</i>, will eventually be resident in the application context.
* <p>Only a single auto-proxy creator should be registered and multiple configuration
* elements may wish to register different concrete implementations. As such this class
* delegates to {@link AopConfigUtils} which provides a simple escalation protocol.
* Callers may request a particular auto-proxy creator and know that creator,
* <i>or a more capable variant thereof</i>, will be registered as a post-processor.
*
* @author Rob Harrop
* @author Juergen Hoeller
@@ -81,11 +81,11 @@ public abstract class AopNamespaceUtils {
private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) {
if (sourceElement != null) {
boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
boolean proxyTargetClass = Boolean.parseBoolean(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
if (proxyTargetClass) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
boolean exposeProxy = Boolean.valueOf(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
boolean exposeProxy = Boolean.parseBoolean(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
if (exposeProxy) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
@@ -94,9 +94,8 @@ public abstract class AopNamespaceUtils {
private static void registerComponentIfNecessary(BeanDefinition beanDefinition, ParserContext parserContext) {
if (beanDefinition != null) {
BeanComponentDefinition componentDefinition =
new BeanComponentDefinition(beanDefinition, AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME);
parserContext.registerComponent(componentDefinition);
parserContext.registerComponent(
new BeanComponentDefinition(beanDefinition, AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME));
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,8 +21,8 @@ import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.core.Ordered;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
* Implementation of {@link AspectInstanceFactory} that locates the aspect from the
@@ -50,9 +50,7 @@ public class SimpleBeanFactoryAwareAspectInstanceFactory implements AspectInstan
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
if (!StringUtils.hasText(this.aspectBeanName)) {
throw new IllegalArgumentException("'aspectBeanName' is required");
}
Assert.notNull(this.aspectBeanName, "'aspectBeanName' is required");
}
@@ -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.
@@ -90,7 +90,7 @@ public abstract class AbstractAdvisingBeanPostProcessor extends ProxyProcessorSu
return proxyFactory.getProxy(getProxyClassLoader());
}
// No async proxy needed.
// No proxy needed.
return bean;
}
@@ -155,7 +155,7 @@ public abstract class AbstractAdvisingBeanPostProcessor extends ProxyProcessorSu
* Subclasses may choose to implement this: for example,
* to change the interfaces exposed.
* <p>The default implementation is empty.
* @param proxyFactory ProxyFactory that is already configured with
* @param proxyFactory the ProxyFactory that is already configured with
* target, advisor and interfaces and will be used to create the proxy
* immediately after this method returns
* @since 4.2.3
@@ -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.
@@ -22,7 +22,6 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -93,7 +92,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
* List of Advisors. If an Advice is added, it will be wrapped
* in an Advisor before being added to this List.
*/
private List<Advisor> advisors = new LinkedList<Advisor>();
private List<Advisor> advisors = new ArrayList<Advisor>();
/**
* Array updated on changes to the advisors list, which is easier
@@ -234,7 +233,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
@Override
public Class<?>[] getProxiedInterfaces() {
return this.interfaces.toArray(new Class<?>[this.interfaces.size()]);
return ClassUtils.toClassArray(this.interfaces);
}
@Override
@@ -480,7 +479,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
* for the given method, based on this configuration.
* @param method the proxied method
* @param targetClass the target class
* @return List of MethodInterceptors (may also include InterceptorAndDynamicMethodMatchers)
* @return a List of MethodInterceptors (may also include InterceptorAndDynamicMethodMatchers)
*/
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
MethodCacheKey cacheKey = new MethodCacheKey(method);
@@ -534,7 +533,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
/**
* Build a configuration-only copy of this AdvisedSupport,
* replacing the TargetSource
* replacing the TargetSource.
*/
AdvisedSupport getConfigurationOnlyCopy() {
AdvisedSupport copy = new AdvisedSupport();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -43,6 +43,25 @@ import org.springframework.util.ObjectUtils;
*/
public abstract class AopProxyUtils {
/**
* Obtain the singleton target object behind the given proxy, if any.
* @param candidate the (potential) proxy to check
* @return the singleton target object managed in a {@link SingletonTargetSource},
* or {@code null} in any other case (not a proxy, not an existing singleton target)
* @since 4.3.8
* @see Advised#getTargetSource()
* @see SingletonTargetSource#getTarget()
*/
public static Object getSingletonTarget(Object candidate) {
if (candidate instanceof Advised) {
TargetSource targetSource = ((Advised) candidate).getTargetSource();
if (targetSource instanceof SingletonTargetSource) {
return ((SingletonTargetSource) targetSource).getTarget();
}
}
return null;
}
/**
* Determine the ultimate target class of the given bean instance, traversing
* not only a top-level proxy but any number of nested proxies as well &mdash;
@@ -59,14 +78,7 @@ public abstract class AopProxyUtils {
Class<?> result = null;
while (current instanceof TargetClassAware) {
result = ((TargetClassAware) current).getTargetClass();
Object nested = null;
if (current instanceof Advised) {
TargetSource targetSource = ((Advised) current).getTargetSource();
if (targetSource instanceof SingletonTargetSource) {
nested = ((SingletonTargetSource) targetSource).getTarget();
}
}
current = nested;
current = getSingletonTarget(current);
}
if (result == null) {
result = (AopUtils.isCglibProxy(candidate) ? candidate.getClass().getSuperclass() : candidate.getClass());
@@ -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.
@@ -23,6 +23,7 @@ import java.lang.reflect.UndeclaredThrowableException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import org.aopalliance.aop.Advice;
@@ -56,9 +57,6 @@ import org.springframework.util.ObjectUtils;
/**
* CGLIB-based {@link AopProxy} implementation for the Spring AOP framework.
*
* <p>Formerly named {@code Cglib2AopProxy}, as of Spring 3.2, this class depends on
* Spring's own internally repackaged version of CGLIB 3.</i>.
*
* <p>Objects of this type should be obtained through proxy factories,
* configured by an {@link AdvisedSupport} object. This class is internal
* to Spring's AOP framework and need not be used directly by client code.
@@ -203,18 +201,16 @@ class CglibAopProxy implements AopProxy, Serializable {
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of class [" +
this.advised.getTargetClass() + "]: " +
"Common causes of this problem include using a final class or a non-visible class",
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of class [" +
this.advised.getTargetClass() + "]: " +
"Common causes of this problem include using a final class or a non-visible class",
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Exception ex) {
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
@@ -241,10 +237,11 @@ class CglibAopProxy implements AopProxy, Serializable {
* validates it if not.
*/
private void validateClassIfNecessary(Class<?> proxySuperClass, ClassLoader proxyClassLoader) {
if (logger.isInfoEnabled()) {
if (logger.isWarnEnabled()) {
synchronized (validatedClasses) {
if (!validatedClasses.containsKey(proxySuperClass)) {
doValidateClass(proxySuperClass, proxyClassLoader);
doValidateClass(proxySuperClass, proxyClassLoader,
ClassUtils.getAllInterfacesForClassAsSet(proxySuperClass));
validatedClasses.put(proxySuperClass, Boolean.TRUE);
}
}
@@ -255,30 +252,35 @@ class CglibAopProxy implements AopProxy, Serializable {
* Checks for final methods on the given {@code Class}, as well as package-visible
* methods across ClassLoaders, and writes warnings to the log for each one found.
*/
private void doValidateClass(Class<?> proxySuperClass, ClassLoader proxyClassLoader) {
if (Object.class != proxySuperClass) {
private void doValidateClass(Class<?> proxySuperClass, ClassLoader proxyClassLoader, Set<Class<?>> ifcs) {
if (proxySuperClass != Object.class) {
Method[] methods = proxySuperClass.getDeclaredMethods();
for (Method method : methods) {
int mod = method.getModifiers();
if (!Modifier.isStatic(mod)) {
if (!Modifier.isStatic(mod) && !Modifier.isPrivate(mod)) {
if (Modifier.isFinal(mod)) {
logger.info("Unable to proxy method [" + method + "] because it is final: " +
"All calls to this method via a proxy will NOT be routed to the target instance.");
if (implementsInterface(method, ifcs)) {
logger.warn("Unable to proxy interface-implementing method [" + method + "] because " +
"it is marked as final: Consider using interface-based JDK proxies instead!");
}
logger.info("Final method [" + method + "] cannot get proxied via CGLIB: " +
"Calls to this method will NOT be routed to the target instance and " +
"might lead to NPEs against uninitialized fields in the proxy instance.");
}
else if (!Modifier.isPublic(mod) && !Modifier.isProtected(mod) && !Modifier.isPrivate(mod) &&
else if (!Modifier.isPublic(mod) && !Modifier.isProtected(mod) &&
proxyClassLoader != null && proxySuperClass.getClassLoader() != proxyClassLoader) {
logger.info("Unable to proxy method [" + method + "] because it is package-visible " +
"across different ClassLoaders: All calls to this method via a proxy will " +
"NOT be routed to the target instance.");
logger.info("Method [" + method + "] is package-visible across different ClassLoaders " +
"and cannot get proxied via CGLIB: Declare this method as public or protected " +
"if you need to support invocations through the proxy.");
}
}
}
doValidateClass(proxySuperClass.getSuperclass(), proxyClassLoader);
doValidateClass(proxySuperClass.getSuperclass(), proxyClassLoader, ifcs);
}
}
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
// Parameters used for optimisation choices...
// Parameters used for optimization choices...
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();
@@ -290,20 +292,20 @@ class CglibAopProxy implements AopProxy, Serializable {
// unadvised but can return this). May be required to expose the proxy.
Callback targetInterceptor;
if (exposeProxy) {
targetInterceptor = isStatic ?
targetInterceptor = (isStatic ?
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
}
else {
targetInterceptor = isStatic ?
targetInterceptor = (isStatic ?
new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedInterceptor(this.advised.getTargetSource());
new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
}
// Choose a "direct to target" dispatcher (used for
// unadvised calls to static targets that cannot return this).
Callback targetDispatcher = isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp();
Callback targetDispatcher = (isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());
Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // for normal advice
@@ -317,14 +319,14 @@ class CglibAopProxy implements AopProxy, Serializable {
Callback[] callbacks;
// If the target is a static one and the advice chain is frozen,
// then we can make some optimisations by sending the AOP calls
// then we can make some optimizations by sending the AOP calls
// direct to the target using the fixed chain for that method.
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap<String, Integer>(methods.length);
// TODO: small memory optimisation here (can skip creation for methods with no advice)
// TODO: small memory optimization here (can skip creation for methods with no advice)
for (int x = 0; x < methods.length; x++) {
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
@@ -345,25 +347,6 @@ class CglibAopProxy implements AopProxy, Serializable {
return callbacks;
}
/**
* Process a return value. Wraps a return of {@code this} if necessary to be the
* {@code proxy} and also verifies that {@code null} is not returned as a primitive.
*/
private static Object processReturnType(Object proxy, Object target, Method method, Object retVal) {
// Massage return value if necessary
if (retVal != null && retVal == target && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this". Note that we can't help
// if the target sets a reference to itself in another returned object.
retVal = proxy;
}
Class<?> returnType = method.getReturnType();
if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
@Override
public boolean equals(Object other) {
@@ -377,6 +360,39 @@ class CglibAopProxy implements AopProxy, Serializable {
}
/**
* Check whether the given method is declared on any of the given interfaces.
*/
private static boolean implementsInterface(Method method, Set<Class<?>> ifcs) {
for (Class<?> ifc : ifcs) {
if (ClassUtils.hasMethod(ifc, method.getName(), method.getParameterTypes())) {
return true;
}
}
return false;
}
/**
* Process a return value. Wraps a return of {@code this} if necessary to be the
* {@code proxy} and also verifies that {@code null} is not returned as a primitive.
*/
private static Object processReturnType(Object proxy, Object target, Method method, Object retVal) {
// Massage return value if necessary
if (retVal != null && retVal == target &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this". Note that we can't help
// if the target sets a reference to itself in another returned object.
retVal = proxy;
}
Class<?> returnType = method.getReturnType();
if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
/**
* Serializable replacement for CGLIB's NoOp interface.
* Public to allow use elsewhere in the framework.
@@ -794,12 +810,16 @@ class CglibAopProxy implements AopProxy, Serializable {
}
// We must always proxy equals, to direct calls to this.
if (AopUtils.isEqualsMethod(method)) {
logger.debug("Found 'equals' method: " + method);
if (logger.isDebugEnabled()) {
logger.debug("Found 'equals' method: " + method);
}
return INVOKE_EQUALS;
}
// We must always calculate hashCode based on the proxy.
if (AopUtils.isHashCodeMethod(method)) {
logger.debug("Found 'hashCode' method: " + method);
if (logger.isDebugEnabled()) {
logger.debug("Found 'hashCode' method: " + method);
}
return INVOKE_HASHCODE;
}
Class<?> targetClass = this.advised.getTargetClass();
@@ -822,51 +842,42 @@ class CglibAopProxy implements AopProxy, Serializable {
// Else use the AOP_PROXY.
if (isStatic && isFrozen && this.fixedInterceptorMap.containsKey(key)) {
if (logger.isDebugEnabled()) {
logger.debug("Method has advice and optimisations are enabled: " + method);
logger.debug("Method has advice and optimizations are enabled: " + method);
}
// We know that we are optimising so we can use the FixedStaticChainInterceptors.
// We know that we are optimizing so we can use the FixedStaticChainInterceptors.
int index = this.fixedInterceptorMap.get(key);
return (index + this.fixedInterceptorOffset);
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Unable to apply any optimisations to advised method: " + method);
logger.debug("Unable to apply any optimizations to advised method: " + method);
}
return AOP_PROXY;
}
}
else {
// See if the return type of the method is outside the class hierarchy
// of the target type. If so we know it never needs to have return type
// massage and can use a dispatcher.
// If the proxy is being exposed, then must use the interceptor the
// correct one is already configured. If the target is not static, then
// cannot use a dispatcher because the target cannot be released.
// See if the return type of the method is outside the class hierarchy of the target type.
// If so we know it never needs to have return type massage and can use a dispatcher.
// If the proxy is being exposed, then must use the interceptor the correct one is already
// configured. If the target is not static, then we cannot use a dispatcher because the
// target needs to be explicitly released after the invocation.
if (exposeProxy || !isStatic) {
return INVOKE_TARGET;
}
Class<?> returnType = method.getReturnType();
if (targetClass == returnType) {
if (returnType.isAssignableFrom(targetClass)) {
if (logger.isDebugEnabled()) {
logger.debug("Method " + method +
"has return type same as target type (may return this) - using INVOKE_TARGET");
logger.debug("Method return type is assignable from target type and " +
"may therefore return 'this' - using INVOKE_TARGET: " + method);
}
return INVOKE_TARGET;
}
else if (returnType.isPrimitive() || !returnType.isAssignableFrom(targetClass)) {
if (logger.isDebugEnabled()) {
logger.debug("Method " + method +
" has return type that ensures this cannot be returned- using DISPATCH_TARGET");
}
return DISPATCH_TARGET;
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Method " + method +
"has return type that is assignable from the target type (may return this) - " +
"using INVOKE_TARGET");
logger.debug("Method return type ensures 'this' cannot be returned - " +
"using DISPATCH_TARGET: " + method);
}
return INVOKE_TARGET;
return DISPATCH_TARGET;
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 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.
@@ -62,9 +62,9 @@ public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializ
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
@@ -98,8 +98,7 @@ public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializ
* Determine whether the Advisors contain matching introductions.
*/
private static boolean hasMatchingIntroductions(Advised config, Class<?> actualClass) {
for (int i = 0; i < config.getAdvisors().length; i++) {
Advisor advisor = config.getAdvisors()[i];
for (Advisor advisor : config.getAdvisors()) {
if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (ia.getClassFilter().matches(actualClass)) {
@@ -215,7 +215,8 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
// Massage return value if necessary.
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target && returnType.isInstance(proxy) &&
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 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.
@@ -34,7 +34,7 @@ public class ProxyCreatorSupport extends AdvisedSupport {
private AopProxyFactory aopProxyFactory;
private List<AdvisedSupportListener> listeners = new LinkedList<AdvisedSupportListener>();
private final List<AdvisedSupportListener> listeners = new LinkedList<AdvisedSupportListener>();
/** Set to true when the first AOP proxy has been created */
private boolean active = false;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 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.
@@ -640,7 +640,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
}
public String getBeanName() {
return beanName;
return this.beanName;
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 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.
@@ -16,6 +16,8 @@
package org.springframework.aop.framework;
import java.io.Closeable;
import org.springframework.beans.factory.Aware;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.DisposableBean;
@@ -48,9 +50,9 @@ public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanC
/**
* Set the ordering which will apply to this class's implementation
* of Ordered, used when applying multiple processors.
* <p>Default value is {@code Integer.MAX_VALUE}, meaning that it's non-ordered.
* Set the ordering which will apply to this processor's implementation
* of {@link Ordered}, used when applying multiple processors.
* <p>The default value is {@code Ordered.LOWEST_PRECEDENCE}, meaning non-ordered.
* @param order the ordering value
*/
public void setOrder(int order) {
@@ -127,6 +129,7 @@ public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanC
*/
protected boolean isConfigurationCallbackInterface(Class<?> ifc) {
return (InitializingBean.class == ifc || DisposableBean.class == ifc ||
Closeable.class == ifc || "java.lang.AutoCloseable".equals(ifc.getName()) ||
ObjectUtils.containsElement(ifc.getInterfaces(), Aware.class));
}
@@ -139,7 +142,9 @@ public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanC
* @return whether the given interface is an internal language interface
*/
protected boolean isInternalLanguageInterface(Class<?> ifc) {
return ifc.getName().equals("groovy.lang.GroovyObject");
return (ifc.getName().equals("groovy.lang.GroovyObject") ||
ifc.getName().endsWith(".cglib.proxy.Factory") ||
ifc.getName().endsWith(".bytebuddy.MockAccess"));
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 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.
@@ -31,15 +31,15 @@ import org.springframework.aop.Advisor;
public interface AdvisorAdapterRegistry {
/**
* Return an Advisor wrapping the given advice.
* Return an {@link Advisor} wrapping the given advice.
* <p>Should by default at least support
* {@link org.aopalliance.intercept.MethodInterceptor},
* {@link org.springframework.aop.MethodBeforeAdvice},
* {@link org.springframework.aop.AfterReturningAdvice},
* {@link org.springframework.aop.ThrowsAdvice}.
* @param advice object that should be an advice
* @return an Advisor wrapping the given advice. Never returns {@code null}.
* If the advice parameter is an Advisor, return it.
* @return an Advisor wrapping the given advice (never {@code null};
* if the advice parameter is an Advisor, it is to be returned as-is)
* @throws UnknownAdviceTypeException if no registered advisor adapter
* can wrap the supposed advice
*/
@@ -48,21 +48,20 @@ public interface AdvisorAdapterRegistry {
/**
* Return an array of AOP Alliance MethodInterceptors to allow use of the
* given Advisor in an interception-based framework.
* <p>Don't worry about the pointcut associated with the Advisor,
* if it's a PointcutAdvisor: just return an interceptor.
* <p>Don't worry about the pointcut associated with the {@link Advisor}, if it is
* a {@link org.springframework.aop.PointcutAdvisor}: just return an interceptor.
* @param advisor Advisor to find an interceptor for
* @return an array of MethodInterceptors to expose this Advisor's behavior
* @throws UnknownAdviceTypeException if the Advisor type is
* not understood by any registered AdvisorAdapter.
* not understood by any registered AdvisorAdapter
*/
MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException;
/**
* Register the given AdvisorAdapter. Note that it is not necessary to register
* Register the given {@link AdvisorAdapter}. Note that it is not necessary to register
* adapters for an AOP Alliance Interceptors or Spring Advices: these must be
* automatically recognized by an AdvisorAdapterRegistry implementation.
* @param adapter AdvisorAdapter that understands a particular Advisor
* or Advice types
* automatically recognized by an {@code AdvisorAdapterRegistry} implementation.
* @param adapter AdvisorAdapter that understands particular Advisor or Advice types
*/
void registerAdvisorAdapter(AdvisorAdapter adapter);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 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,11 +26,13 @@ import org.springframework.aop.AfterReturningAdvice;
import org.springframework.util.Assert;
/**
* Interceptor to wrap am {@link org.springframework.aop.AfterReturningAdvice}.
* Interceptor to wrap an {@link org.springframework.aop.AfterReturningAdvice}.
* Used internally by the AOP framework; application developers should not need
* to use this class directly.
*
* @author Rod Johnson
* @see MethodBeforeAdviceInterceptor
* @see ThrowsAdviceInterceptor
*/
@SuppressWarnings("serial")
public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {
@@ -47,6 +49,7 @@ public class AfterReturningAdviceInterceptor implements MethodInterceptor, After
this.advice = advice;
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
Object retVal = mi.proceed();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 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.
@@ -21,6 +21,7 @@ import java.io.Serializable;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.BeforeAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.util.Assert;
@@ -30,11 +31,13 @@ import org.springframework.util.Assert;
* to use this class directly.
*
* @author Rod Johnson
* @see AfterReturningAdviceInterceptor
* @see ThrowsAdviceInterceptor
*/
@SuppressWarnings("serial")
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
private MethodBeforeAdvice advice;
private final MethodBeforeAdvice advice;
/**
@@ -46,9 +49,10 @@ public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Seriali
this.advice = advice;
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}
@@ -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.
@@ -50,6 +50,8 @@ import org.springframework.util.Assert;
*
* @author Rod Johnson
* @author Juergen Hoeller
* @see MethodBeforeAdviceInterceptor
* @see AfterReturningAdviceInterceptor
*/
public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice {
@@ -66,9 +68,8 @@ public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice {
/**
* Create a new ThrowsAdviceInterceptor for the given ThrowsAdvice.
* @param throwsAdvice the advice object that defines the exception
* handler methods (usually a {@link org.springframework.aop.ThrowsAdvice}
* implementation)
* @param throwsAdvice the advice object that defines the exception handler methods
* (usually a {@link org.springframework.aop.ThrowsAdvice} implementation)
*/
public ThrowsAdviceInterceptor(Object throwsAdvice) {
Assert.notNull(throwsAdvice, "Advice must not be null");
@@ -76,14 +77,17 @@ public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice {
Method[] methods = throwsAdvice.getClass().getMethods();
for (Method method : methods) {
if (method.getName().equals(AFTER_THROWING) &&
(method.getParameterTypes().length == 1 || method.getParameterTypes().length == 4) &&
Throwable.class.isAssignableFrom(method.getParameterTypes()[method.getParameterTypes().length - 1])
) {
// Have an exception handler
this.exceptionHandlerMap.put(method.getParameterTypes()[method.getParameterTypes().length - 1], method);
if (logger.isDebugEnabled()) {
logger.debug("Found exception handler method: " + method);
if (method.getName().equals(AFTER_THROWING)) {
Class<?>[] paramTypes = method.getParameterTypes();
if (paramTypes.length == 1 || paramTypes.length == 4) {
Class<?> throwableParam = paramTypes[paramTypes.length - 1];
if (Throwable.class.isAssignableFrom(throwableParam)) {
// An exception handler to register...
this.exceptionHandlerMap.put(throwableParam, method);
if (logger.isDebugEnabled()) {
logger.debug("Found exception handler method on throws advice: " + method);
}
}
}
}
}
@@ -94,14 +98,33 @@ public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice {
}
}
/**
* Return the number of handler methods in this advice.
*/
public int getHandlerMethodCount() {
return this.exceptionHandlerMap.size();
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
catch (Throwable ex) {
Method handlerMethod = getExceptionHandler(ex);
if (handlerMethod != null) {
invokeHandlerMethod(mi, ex, handlerMethod);
}
throw ex;
}
}
/**
* Determine the exception handle method. Can return null if not found.
* Determine the exception handle method for the given exception.
* @param exception the exception thrown
* @return a handler for the given exception type
* @return a handler for the given exception type, or {@code null} if none found
*/
private Method getExceptionHandler(Throwable exception) {
Class<?> exceptionClass = exception.getClass();
@@ -119,24 +142,10 @@ public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice {
return handler;
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
catch (Throwable ex) {
Method handlerMethod = getExceptionHandler(ex);
if (handlerMethod != null) {
invokeHandlerMethod(mi, ex, handlerMethod);
}
throw ex;
}
}
private void invokeHandlerMethod(MethodInvocation mi, Throwable ex, Method method) throws Throwable {
Object[] handlerArgs;
if (method.getParameterTypes().length == 1) {
handlerArgs = new Object[] { ex };
handlerArgs = new Object[] {ex};
}
else {
handlerArgs = new Object[] {mi.getMethod(), mi.getArguments(), mi.getThis(), ex};
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -54,7 +54,8 @@ public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyC
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalStateException("Cannot use AdvisorAutoProxyCreator without a ConfigurableListableBeanFactory");
throw new IllegalArgumentException(
"AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
}
initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}
@@ -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.
@@ -55,26 +55,25 @@ import org.springframework.util.StringUtils;
* before invoking the bean itself.
*
* <p>This class distinguishes between "common" interceptors: shared for all proxies it
* creates, and "specific" interceptors: unique per bean instance. There need not
* be any common interceptors. If there are, they are set using the interceptorNames
* property. As with ProxyFactoryBean, interceptors names in the current factory
* are used rather than bean references to allow correct handling of prototype
* advisors and interceptors: for example, to support stateful mixins.
* Any advice type is supported for "interceptorNames" entries.
* creates, and "specific" interceptors: unique per bean instance. There need not be any
* common interceptors. If there are, they are set using the interceptorNames property.
* As with {@link org.springframework.aop.framework.ProxyFactoryBean}, interceptors names
* in the current factory are used rather than bean references to allow correct handling
* of prototype advisors and interceptors: for example, to support stateful mixins.
* Any advice type is supported for {@link #setInterceptorNames "interceptorNames"} entries.
*
* <p>Such auto-proxying is particularly useful if there's a large number of beans that
* need to be wrapped with similar proxies, i.e. delegating to the same interceptors.
* Instead of x repetitive proxy definitions for x target beans, you can register
* one single such post processor with the bean factory to achieve the same effect.
*
* <p>Subclasses can apply any strategy to decide if a bean is to be proxied,
* e.g. by type, by name, by definition details, etc. They can also return
* additional interceptors that should just be applied to the specific bean
* instance. The default concrete implementation is BeanNameAutoProxyCreator,
* identifying the beans to be proxied via a list of bean names.
* <p>Subclasses can apply any strategy to decide if a bean is to be proxied, e.g. by type,
* by name, by definition details, etc. They can also return additional interceptors that
* should just be applied to the specific bean instance. A simple concrete implementation is
* {@link BeanNameAutoProxyCreator}, identifying the beans to be proxied via given names.
*
* <p>Any number of {@link TargetSourceCreator} implementations can be used to create
* a custom target source - for example, to pool prototype objects. Auto-proxying will
* a custom target source: for example, to pool prototype objects. Auto-proxying will
* occur even if there is no advice, as long as a TargetSourceCreator specifies a custom
* {@link org.springframework.aop.TargetSource}. If there are no TargetSourceCreators set,
* or if none matches, a {@link org.springframework.aop.target.SingletonTargetSource}
@@ -156,8 +155,8 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
}
/**
* Specify the AdvisorAdapterRegistry to use.
* Default is the global AdvisorAdapterRegistry.
* Specify the {@link AdvisorAdapterRegistry} to use.
* <p>Default is the global {@link AdvisorAdapterRegistry}.
* @see org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry
*/
public void setAdvisorAdapterRegistry(AdvisorAdapterRegistry advisorAdapterRegistry) {
@@ -165,18 +164,18 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
}
/**
* Set custom TargetSourceCreators to be applied in this order.
* If the list is empty, or they all return null, a SingletonTargetSource
* Set custom {@code TargetSourceCreators} to be applied in this order.
* If the list is empty, or they all return null, a {@link SingletonTargetSource}
* will be created for each bean.
* <p>Note that TargetSourceCreators will kick in even for target beans
* where no advices or advisors have been found. If a TargetSourceCreator
* returns a TargetSource for a specific bean, that bean will be proxied
* where no advices or advisors have been found. If a {@code TargetSourceCreator}
* returns a {@link TargetSource} for a specific bean, that bean will be proxied
* in any case.
* <p>TargetSourceCreators can only be invoked if this post processor is used
* in a BeanFactory, and its BeanFactoryAware callback is used.
* @param targetSourceCreators list of TargetSourceCreator.
* Ordering is significant: The TargetSource returned from the first matching
* TargetSourceCreator (that is, the first that returns non-null) will be used.
* <p>{@code TargetSourceCreators} can only be invoked if this post processor is used
* in a {@link BeanFactory} and its {@link BeanFactoryAware} callback is triggered.
* @param targetSourceCreators the list of {@code TargetSourceCreators}.
* Ordering is significant: The {@code TargetSource} returned from the first matching
* {@code TargetSourceCreator} (that is, the first that returns non-null) will be used.
*/
public void setCustomTargetSourceCreators(TargetSourceCreator... targetSourceCreators) {
this.customTargetSourceCreators = targetSourceCreators;
@@ -207,8 +206,8 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
}
/**
* Return the owning BeanFactory.
* May be {@code null}, as this object doesn't need to belong to a bean factory.
* Return the owning {@link BeanFactory}.
* May be {@code null}, as this post-processor doesn't need to belong to a bean factory.
*/
protected BeanFactory getBeanFactory() {
return this.beanFactory;
@@ -413,7 +412,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
// Found a matching TargetSource.
if (logger.isDebugEnabled()) {
logger.debug("TargetSourceCreator [" + tsc +
" found custom TargetSource for bean with name '" + beanName + "'");
"] found custom TargetSource for bean with name '" + beanName + "'");
}
return ts;
}
@@ -455,10 +454,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
for (Advisor advisor : advisors) {
proxyFactory.addAdvisor(advisor);
}
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
@@ -557,7 +553,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
* Subclasses may choose to implement this: for example,
* to change the interfaces exposed.
* <p>The default implementation is empty.
* @param proxyFactory ProxyFactory that is already configured with
* @param proxyFactory a ProxyFactory that is already configured with
* TargetSource and interfaces and will be used to create the proxy
* immediately after this method returns
*/
@@ -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.
@@ -16,7 +16,7 @@
package org.springframework.aop.framework.autoproxy;
import java.util.LinkedList;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
@@ -43,7 +43,7 @@ public class BeanFactoryAdvisorRetrievalHelper {
private final ConfigurableListableBeanFactory beanFactory;
private String[] cachedAdvisorBeanNames;
private volatile String[] cachedAdvisorBeanNames;
/**
@@ -64,22 +64,19 @@ public class BeanFactoryAdvisorRetrievalHelper {
*/
public List<Advisor> findAdvisorBeans() {
// Determine list of advisor bean names, if not cached already.
String[] advisorNames = null;
synchronized (this) {
advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the auto-proxy creator apply to them!
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the auto-proxy creator apply to them!
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
if (advisorNames.length == 0) {
return new LinkedList<Advisor>();
return new ArrayList<Advisor>();
}
List<Advisor> advisors = new LinkedList<Advisor>();
List<Advisor> advisors = new ArrayList<Advisor>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
if (this.beanFactory.isCurrentlyInCreation(name)) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,15 +19,16 @@ package org.springframework.aop.framework.autoproxy;
import org.springframework.beans.factory.BeanNameAware;
/**
* BeanPostProcessor implementation that creates AOP proxies based on all candidate
* Advisors in the current BeanFactory. This class is completely generic; it contains
* no special code to handle any particular aspects, such as pooling aspects.
* {@code BeanPostProcessor} implementation that creates AOP proxies based on all
* candidate {@code Advisor}s in the current {@code BeanFactory}. This class is
* completely generic; it contains no special code to handle any particular aspects,
* such as pooling aspects.
*
* <p>It's possible to filter out advisors - for example, to use multiple post processors
* of this type in the same factory - by setting the {@code usePrefix} property
* to true, in which case only advisors beginning with the DefaultAdvisorAutoProxyCreator's
* bean name followed by a dot (like "aapc.") will be used. This default prefix can be
* changed from the bean name by setting the {@code advisorBeanNamePrefix} property.
* of this type in the same factory - by setting the {@code usePrefix} property to true,
* in which case only advisors beginning with the DefaultAdvisorAutoProxyCreator's bean
* name followed by a dot (like "aapc.") will be used. This default prefix can be changed
* from the bean name by setting the {@code advisorBeanNamePrefix} property.
* The separator (.) will also be used in this case.
*
* @author Rod Johnson
@@ -40,22 +41,22 @@ public class DefaultAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCrea
public final static String SEPARATOR = ".";
private boolean usePrefix;
private boolean usePrefix = false;
private String advisorBeanNamePrefix;
/**
* Set whether to exclude advisors with a certain prefix
* in the bean name.
* Set whether to only include advisors with a certain prefix in the bean name.
* <p>Default is {@code false}, including all beans of type {@code Advisor}.
* @see #setAdvisorBeanNamePrefix
*/
public void setUsePrefix(boolean usePrefix) {
this.usePrefix = usePrefix;
}
/**
* Return whether to exclude advisors with a certain prefix
* in the bean name.
* Return whether to only include advisors with a certain prefix in the bean name.
*/
public boolean isUsePrefix() {
return this.usePrefix;
@@ -89,7 +90,7 @@ public class DefaultAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCrea
/**
* Consider Advisor beans with the specified prefix as eligible, if activated.
* Consider {@code Advisor} beans with the specified prefix as eligible, if activated.
* @see #setUsePrefix
* @see #setAdvisorBeanNamePrefix
*/
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 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.
@@ -150,7 +150,7 @@ public abstract class AbstractBeanFactoryBasedTargetSourceCreator
// since those are only meant to apply to beans defined in the original factory.
for (Iterator<BeanPostProcessor> it = internalBeanFactory.getBeanPostProcessors().iterator(); it.hasNext();) {
if (it.next() instanceof AopInfrastructureBean) {
it.remove();
it.remove(); // effectively deprecated: use List.removeIf on Java 8+
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,12 +22,12 @@ import org.aopalliance.intercept.MethodInvocation;
/**
* Base class for monitoring interceptors, such as performance monitors.
* Provides {@code prefix} and {@code suffix} properties
* that help to classify/group performance monitoring results.
* Provides configurable "prefix and "suffix" properties that help to
* classify/group performance monitoring results.
*
* <p>Subclasses should call the {@code createInvocationTraceName(MethodInvocation)}
* method to create a name for the given trace that includes information about the
* method invocation under trace along with the prefix and suffix added as appropriate.
* <p>In their {@link #invokeUnderTrace} implementation, subclasses should call the
* {@link #createInvocationTraceName} method to create a name for the given trace,
* including information about the method invocation along with a prefix/suffix.
*
* @author Rob Harrop
* @author Juergen Hoeller
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 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,12 @@ public abstract class AbstractTraceInterceptor implements MethodInterceptor, Ser
*/
private boolean hideProxyClassNames = false;
/**
* Indicates whether to pass an exception to the logger.
* @see #writeToLog(Log, String, Throwable)
*/
private boolean logExceptionStackTrace = true;
/**
* Set whether to use a dynamic logger or a static logger.
@@ -98,6 +104,17 @@ public abstract class AbstractTraceInterceptor implements MethodInterceptor, Ser
this.hideProxyClassNames = hideProxyClassNames;
}
/**
* Set whether to pass an exception to the logger, suggesting inclusion
* of its stack trace into the log. Default is "true"; set this to "false"
* in order to reduce the log output to just the trace message (which may
* include the exception class name and exception message, if applicable).
* @since 4.3.10
*/
public void setLogExceptionStackTrace(boolean logExceptionStackTrace) {
this.logExceptionStackTrace = logExceptionStackTrace;
}
/**
* Determines whether or not logging is enabled for the particular {@code MethodInvocation}.
@@ -171,6 +188,40 @@ public abstract class AbstractTraceInterceptor implements MethodInterceptor, Ser
return logger.isTraceEnabled();
}
/**
* Write the supplied trace message to the supplied {@code Log} instance.
* <p>To be called by {@link #invokeUnderTrace} for enter/exit messages.
* <p>Delegates to {@link #writeToLog(Log, String, Throwable)} as the
* ultimate delegate that controls the underlying logger invocation.
* @since 4.3.10
* @see #writeToLog(Log, String, Throwable)
*/
protected void writeToLog(Log logger, String message) {
writeToLog(logger, message, null);
}
/**
* Write the supplied trace message and {@link Throwable} to the
* supplied {@code Log} instance.
* <p>To be called by {@link #invokeUnderTrace} for enter/exit outcomes,
* potentially including an exception. Note that an exception's stack trace
* won't get logged when {@link #setLogExceptionStackTrace} is "false".
* <p>By default messages are written at {@code TRACE} level. Subclasses
* can override this method to control which level the message is written
* at, typically also overriding {@link #isLogEnabled} accordingly.
* @since 4.3.10
* @see #setLogExceptionStackTrace
* @see #isLogEnabled
*/
protected void writeToLog(Log logger, String message, Throwable ex) {
if (ex != null && this.logExceptionStackTrace) {
logger.trace(message, ex);
}
else {
logger.trace(message);
}
}
/**
* Subclasses must override this method to perform any tracing around the
@@ -180,13 +231,15 @@ public abstract class AbstractTraceInterceptor implements MethodInterceptor, Ser
* <p>By default, the passed-in {@code Log} instance will have log level
* "trace" enabled. Subclasses do not have to check for this again, unless
* they overwrite the {@code isInterceptorEnabled} method to modify
* the default behavior.
* the default behavior, and may delegate to {@code writeToLog} for actual
* messages to be written.
* @param logger the {@code Log} to write trace messages to
* @return the result of the call to {@code MethodInvocation.proceed()}
* @throws Throwable if the call to {@code MethodInvocation.proceed()}
* encountered any errors
* @see #isInterceptorEnabled
* @see #isLogEnabled
* @see #writeToLog(Log, String)
* @see #writeToLog(Log, String, Throwable)
*/
protected abstract Object invokeUnderTrace(MethodInvocation invocation, Log logger) throws Throwable;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -228,6 +228,7 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
return beanFactory.getBean(TaskExecutor.class);
}
catch (NoUniqueBeanDefinitionException ex) {
logger.debug("Could not find unique TaskExecutor bean", ex);
try {
return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
}
@@ -241,8 +242,14 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
}
catch (NoSuchBeanDefinitionException ex) {
logger.debug("Could not find default TaskExecutor bean", ex);
try {
return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
}
catch (NoSuchBeanDefinitionException ex2) {
logger.info("No task executor bean found for async processing: " +
"no bean of type TaskExecutor and no bean named 'taskExecutor' either");
}
// Giving up -> either using local default executor or none at all...
logger.info("No TaskExecutor bean found for async processing");
}
}
return null;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -128,20 +128,20 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
/**
* The default message used for writing method entry messages.
*/
private static final String DEFAULT_ENTER_MESSAGE =
"Entering method '" + PLACEHOLDER_METHOD_NAME + "' of class [" + PLACEHOLDER_TARGET_CLASS_NAME + "]";
private static final String DEFAULT_ENTER_MESSAGE = "Entering method '" +
PLACEHOLDER_METHOD_NAME + "' of class [" + PLACEHOLDER_TARGET_CLASS_NAME + "]";
/**
* The default message used for writing method exit messages.
*/
private static final String DEFAULT_EXIT_MESSAGE =
"Exiting method '" + PLACEHOLDER_METHOD_NAME + "' of class [" + PLACEHOLDER_TARGET_CLASS_NAME + "]";
private static final String DEFAULT_EXIT_MESSAGE = "Exiting method '" +
PLACEHOLDER_METHOD_NAME + "' of class [" + PLACEHOLDER_TARGET_CLASS_NAME + "]";
/**
* The default message used for writing exception messages.
*/
private static final String DEFAULT_EXCEPTION_MESSAGE =
"Exception thrown in method '" + PLACEHOLDER_METHOD_NAME + "' of class [" + PLACEHOLDER_TARGET_CLASS_NAME + "]";
private static final String DEFAULT_EXCEPTION_MESSAGE = "Exception thrown in method '" +
PLACEHOLDER_METHOD_NAME + "' of class [" + PLACEHOLDER_TARGET_CLASS_NAME + "]";
/**
* The {@code Pattern} used to match placeholders.
@@ -182,14 +182,14 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
* </ul>
*/
public void setEnterMessage(String enterMessage) throws IllegalArgumentException {
Assert.hasText(enterMessage, "'enterMessage' must not be empty");
Assert.hasText(enterMessage, "enterMessage must not be empty");
checkForInvalidPlaceholders(enterMessage);
Assert.doesNotContain(enterMessage, PLACEHOLDER_RETURN_VALUE,
"enterMessage cannot contain placeholder [" + PLACEHOLDER_RETURN_VALUE + "]");
"enterMessage cannot contain placeholder " + PLACEHOLDER_RETURN_VALUE);
Assert.doesNotContain(enterMessage, PLACEHOLDER_EXCEPTION,
"enterMessage cannot contain placeholder [" + PLACEHOLDER_EXCEPTION + "]");
"enterMessage cannot contain placeholder " + PLACEHOLDER_EXCEPTION);
Assert.doesNotContain(enterMessage, PLACEHOLDER_INVOCATION_TIME,
"enterMessage cannot contain placeholder [" + PLACEHOLDER_INVOCATION_TIME + "]");
"enterMessage cannot contain placeholder " + PLACEHOLDER_INVOCATION_TIME);
this.enterMessage = enterMessage;
}
@@ -206,10 +206,10 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
* </ul>
*/
public void setExitMessage(String exitMessage) {
Assert.hasText(exitMessage, "'exitMessage' must not be empty");
Assert.hasText(exitMessage, "exitMessage must not be empty");
checkForInvalidPlaceholders(exitMessage);
Assert.doesNotContain(exitMessage, PLACEHOLDER_EXCEPTION,
"exitMessage cannot contain placeholder [" + PLACEHOLDER_EXCEPTION + "]");
"exitMessage cannot contain placeholder" + PLACEHOLDER_EXCEPTION);
this.exitMessage = exitMessage;
}
@@ -225,12 +225,10 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
* </ul>
*/
public void setExceptionMessage(String exceptionMessage) {
Assert.hasText(exceptionMessage, "'exceptionMessage' must not be empty");
Assert.hasText(exceptionMessage, "exceptionMessage must not be empty");
checkForInvalidPlaceholders(exceptionMessage);
Assert.doesNotContain(exceptionMessage, PLACEHOLDER_RETURN_VALUE,
"exceptionMessage cannot contain placeholder [" + PLACEHOLDER_RETURN_VALUE + "]");
Assert.doesNotContain(exceptionMessage, PLACEHOLDER_INVOCATION_TIME,
"exceptionMessage cannot contain placeholder [" + PLACEHOLDER_INVOCATION_TIME + "]");
"exceptionMessage cannot contain placeholder " + PLACEHOLDER_RETURN_VALUE);
this.exceptionMessage = exceptionMessage;
}
@@ -246,7 +244,7 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
*/
@Override
protected Object invokeUnderTrace(MethodInvocation invocation, Log logger) throws Throwable {
String name = invocation.getMethod().getDeclaringClass().getName() + "." + invocation.getMethod().getName();
String name = ClassUtils.getQualifiedMethodName(invocation.getMethod());
StopWatch stopWatch = new StopWatch(name);
Object returnValue = null;
boolean exitThroughException = false;
@@ -262,8 +260,8 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
stopWatch.stop();
}
exitThroughException = true;
writeToLog(logger,
replacePlaceholders(this.exceptionMessage, invocation, null, ex, stopWatch.getTotalTimeMillis()), ex);
writeToLog(logger, replacePlaceholders(
this.exceptionMessage, invocation, null, ex, stopWatch.getTotalTimeMillis()), ex);
throw ex;
}
finally {
@@ -271,35 +269,12 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
if (stopWatch.isRunning()) {
stopWatch.stop();
}
writeToLog(logger,
replacePlaceholders(this.exitMessage, invocation, returnValue, null, stopWatch.getTotalTimeMillis()));
writeToLog(logger, replacePlaceholders(
this.exitMessage, invocation, returnValue, null, stopWatch.getTotalTimeMillis()));
}
}
}
/**
* Writes the supplied message to the supplied {@code Log} instance.
* @see #writeToLog(org.apache.commons.logging.Log, String, Throwable)
*/
protected void writeToLog(Log logger, String message) {
writeToLog(logger, message, null);
}
/**
* Writes the supplied message and {@link Throwable} to the
* supplied {@code Log} instance. By default messages are written
* at {@code TRACE} level. Sub-classes can override this method
* to control which level the message is written at.
*/
protected void writeToLog(Log logger, String message, Throwable ex) {
if (ex != null) {
logger.trace(message, ex);
}
else {
logger.trace(message);
}
}
/**
* Replace the placeholders in the given message with the supplied values,
* or values derived from those supplied.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -121,7 +121,7 @@ public class JamonPerformanceMonitorInterceptor extends AbstractMonitoringInterc
finally {
monitor.stop();
if (!this.trackAllInvocations || isLogEnabled(logger)) {
logger.trace("JAMon performance statistics for method [" + name + "]:\n" + monitor);
writeToLog(logger, "JAMon performance statistics for method [" + name + "]:\n" + monitor);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -63,7 +63,7 @@ public class PerformanceMonitorInterceptor extends AbstractMonitoringInterceptor
}
finally {
stopWatch.stop();
logger.trace(stopWatch.shortSummary());
writeToLog(logger, stopWatch.shortSummary());
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 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.
@@ -29,13 +29,13 @@ import org.apache.commons.logging.LogFactory;
*/
public class SimpleAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHandler {
private final Log logger = LogFactory.getLog(SimpleAsyncUncaughtExceptionHandler.class);
private static final Log logger = LogFactory.getLog(SimpleAsyncUncaughtExceptionHandler.class);
@Override
public void handleUncaughtException(Throwable ex, Method method, Object... params) {
if (logger.isErrorEnabled()) {
logger.error(String.format("Unexpected error occurred invoking async " +
"method '%s'.", method), ex);
logger.error("Unexpected error occurred invoking async method: " + method, ex);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -55,14 +55,14 @@ public class SimpleTraceInterceptor extends AbstractTraceInterceptor {
@Override
protected Object invokeUnderTrace(MethodInvocation invocation, Log logger) throws Throwable {
String invocationDescription = getInvocationDescription(invocation);
logger.trace("Entering " + invocationDescription);
writeToLog(logger, "Entering " + invocationDescription);
try {
Object rval = invocation.proceed();
logger.trace("Exiting " + invocationDescription);
writeToLog(logger, "Exiting " + invocationDescription);
return rval;
}
catch (Throwable ex) {
logger.trace("Exception thrown in " + invocationDescription, ex);
writeToLog(logger, "Exception thrown in " + invocationDescription, ex);
throw ex;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 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.
@@ -50,7 +50,8 @@ import org.springframework.util.ClassUtils;
* @see #setProxyTargetClass
*/
@SuppressWarnings("serial")
public class ScopedProxyFactoryBean extends ProxyConfig implements FactoryBean<Object>, BeanFactoryAware {
public class ScopedProxyFactoryBean extends ProxyConfig
implements FactoryBean<Object>, BeanFactoryAware, AopInfrastructureBean {
/** The TargetSource that manages scoping */
private final SimpleBeanTargetSource scopedTargetSource = new SimpleBeanTargetSource();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -89,7 +89,7 @@ public abstract class ScopedProxyUtils {
}
/**
* Generates the bean name that is used within the scoped proxy to reference the target bean.
* Generate the bean name that is used within the scoped proxy to reference the target bean.
* @param originalBeanName the original name of bean
* @return the generated bean to be used to reference the target bean
*/
@@ -46,7 +46,7 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
private BeanFactory beanFactory;
private transient Advice advice;
private transient volatile Advice advice;
private transient volatile Object adviceMonitor = new Object();
@@ -98,12 +98,28 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
@Override
public Advice getAdvice() {
synchronized (this.adviceMonitor) {
if (this.advice == null && this.adviceBeanName != null) {
Assert.state(this.beanFactory != null, "BeanFactory must be set to resolve 'adviceBeanName'");
this.advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
Advice advice = this.advice;
if (advice != null || this.adviceBeanName == null) {
return advice;
}
Assert.state(this.beanFactory != null, "BeanFactory must be set to resolve 'adviceBeanName'");
if (this.beanFactory.isSingleton(this.adviceBeanName)) {
// Rely on singleton semantics provided by the factory.
advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
this.advice = advice;
return advice;
}
else {
// No singleton guarantees from the factory -> let's lock locally but
// reuse the factory's singleton lock, just in case a lazy dependency
// of our advice bean happens to trigger the singleton lock implicitly...
synchronized (this.adviceMonitor) {
if (this.advice == null) {
this.advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
}
return this.advice;
}
return this.advice;
}
}
@@ -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.
@@ -21,6 +21,7 @@ import java.lang.reflect.Method;
import java.util.Arrays;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
@@ -129,8 +130,9 @@ public abstract class AbstractRegexpMethodPointcut extends StaticMethodMatcherPo
*/
@Override
public boolean matches(Method method, Class<?> targetClass) {
return ((targetClass != null && matchesPattern(targetClass.getName() + "." + method.getName())) ||
matchesPattern(method.getDeclaringClass().getName() + "." + method.getName()));
return ((targetClass != null && targetClass != method.getDeclaringClass() &&
matchesPattern(ClassUtils.getQualifiedMethodName(method, targetClass))) ||
matchesPattern(ClassUtils.getQualifiedMethodName(method, method.getDeclaringClass())));
}
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,7 +22,6 @@ import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* Convenient class for building up pointcuts. All methods return
@@ -188,21 +187,14 @@ public class ComposablePointcut implements Pointcut, Serializable {
if (!(other instanceof ComposablePointcut)) {
return false;
}
ComposablePointcut that = (ComposablePointcut) other;
return ObjectUtils.nullSafeEquals(that.classFilter, this.classFilter) &&
ObjectUtils.nullSafeEquals(that.methodMatcher, this.methodMatcher);
ComposablePointcut otherPointcut = (ComposablePointcut) other;
return (this.classFilter.equals(otherPointcut.classFilter) &&
this.methodMatcher.equals(otherPointcut.methodMatcher));
}
@Override
public int hashCode() {
int code = 17;
if (this.classFilter != null) {
code = 37 * code + this.classFilter.hashCode();
}
if (this.methodMatcher != null) {
code = 37 * code + this.methodMatcher.hashCode();
}
return code;
return this.classFilter.hashCode() * 37 + this.methodMatcher.hashCode();
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,8 +22,6 @@ import java.lang.reflect.Method;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.core.ControlFlow;
import org.springframework.core.ControlFlowFactory;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
@@ -34,7 +32,7 @@ import org.springframework.util.ObjectUtils;
*
* @author Rod Johnson
* @author Rob Harrop
* @see org.springframework.core.ControlFlow
* @author Juergen Hoeller
*/
@SuppressWarnings("serial")
public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher, Serializable {
@@ -43,7 +41,7 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
private String methodName;
private int evaluations;
private volatile int evaluations;
/**
@@ -55,11 +53,11 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
}
/**
* Construct a new pointcut that matches all calls below the
* given method in the given class. If the method name is null,
* matches all control flows below that class.
* Construct a new pointcut that matches all calls below the given method
* in the given class. If no method name is given, matches all control flows
* below the given class.
* @param clazz the clazz
* @param methodName the name of the method
* @param methodName the name of the method (may be {@code null})
*/
public ControlFlowPointcut(Class<?> clazz, String methodName) {
Assert.notNull(clazz, "Class must not be null");
@@ -93,8 +91,14 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
@Override
public boolean matches(Method method, Class<?> targetClass, Object... args) {
this.evaluations++;
ControlFlow cflow = ControlFlowFactory.createControlFlow();
return (this.methodName != null ? cflow.under(this.clazz, this.methodName) : cflow.under(this.clazz));
for (StackTraceElement element : new Throwable().getStackTrace()) {
if (element.getClassName().equals(this.clazz.getName()) &&
(this.methodName == null || element.getMethodName().equals(this.methodName))) {
return true;
}
}
return false;
}
/**
@@ -130,8 +134,7 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
@Override
public int hashCode() {
int code = 17;
code = 37 * code + this.clazz.hashCode();
int code = this.clazz.hashCode();
if (this.methodName != null) {
code = 37 * code + this.methodName.hashCode();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 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.
@@ -45,7 +45,7 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
private final Set<Class<?>> interfaces = new LinkedHashSet<Class<?>>();
private int order = Integer.MAX_VALUE;
private int order = Ordered.LOWEST_PRECEDENCE;
/**
@@ -104,7 +104,7 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
@Override
public Class<?>[] getInterfaces() {
return this.interfaces.toArray(new Class<?>[this.interfaces.size()]);
return ClassUtils.toClassArray(this.interfaces);
}
@Override
@@ -118,7 +118,6 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
}
}
public void setOrder(int order) {
this.order = order;
}
@@ -128,7 +127,6 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
return this.order;
}
@Override
public Advice getAdvice() {
return this.advice;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 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,6 +23,8 @@ import org.springframework.aop.MethodMatcher;
/**
* Convenient abstract superclass for dynamic method matchers,
* which do care about arguments at runtime.
*
* @author Rod Johnson
*/
public abstract class DynamicMethodMatcher implements MethodMatcher {
@@ -24,7 +24,7 @@ import org.springframework.aop.Pointcut;
* Convenient superclass when we want to force subclasses to
* implement MethodMatcher interface, but subclasses
* will want to be pointcuts. The getClassFilter() method can
* be overriden to customize ClassFilter behaviour as well.
* be overridden to customize ClassFilter behaviour as well.
*
* @author Rod Johnson
*/
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 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.
@@ -53,15 +53,15 @@ public class IntroductionInfoSupport implements IntroductionInfo, Serializable {
* due to the delegate implementing it. Call this method to exclude
* internal interfaces from being visible at the proxy level.
* <p>Does nothing if the interface is not implemented by the delegate.
* @param intf the interface to suppress
* @param ifc the interface to suppress
*/
public void suppressInterface(Class<?> intf) {
this.publishedInterfaces.remove(intf);
public void suppressInterface(Class<?> ifc) {
this.publishedInterfaces.remove(ifc);
}
@Override
public Class<?>[] getInterfaces() {
return this.publishedInterfaces.toArray(new Class<?>[this.publishedInterfaces.size()]);
return ClassUtils.toClassArray(this.publishedInterfaces);
}
/**
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,7 +27,7 @@ import org.springframework.util.PatternMatchUtils;
/**
* Pointcut bean for simple method name matches, as alternative to regexp patterns.
* Does not handle overloaded methods: all methods *with a given name will be eligible.
* Does not handle overloaded methods: all methods with a given name will be eligible.
*
* @author Juergen Hoeller
* @author Rod Johnson
@@ -94,7 +94,7 @@ public abstract class Pointcuts {
@SuppressWarnings("serial")
private static class SetterPointcut extends StaticMethodMatcherPointcut implements Serializable {
public static SetterPointcut INSTANCE = new SetterPointcut();
public static final SetterPointcut INSTANCE = new SetterPointcut();
@Override
public boolean matches(Method method, Class<?> targetClass) {
@@ -115,7 +115,7 @@ public abstract class Pointcuts {
@SuppressWarnings("serial")
private static class GetterPointcut extends StaticMethodMatcherPointcut implements Serializable {
public static GetterPointcut INSTANCE = new GetterPointcut();
public static final GetterPointcut INSTANCE = new GetterPointcut();
@Override
public boolean matches(Method method, Class<?> targetClass) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 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.
@@ -21,7 +21,8 @@ import java.io.Serializable;
import org.springframework.aop.ClassFilter;
/**
* Simple ClassFilter implementation that passes classes (and optionally subclasses)
* Simple ClassFilter implementation that passes classes (and optionally subclasses).
*
* @author Rod Johnson
*/
@SuppressWarnings("serial")
@@ -37,7 +38,7 @@ public class RootClassFilter implements ClassFilter, Serializable {
@Override
public boolean matches(Class<?> candidate) {
return clazz.isAssignableFrom(candidate);
return this.clazz.isAssignableFrom(candidate);
}
}
@@ -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.
@@ -23,6 +23,8 @@ import org.springframework.aop.MethodMatcher;
/**
* Convenient abstract superclass for static method matchers, which don't care
* about arguments at runtime.
*
* @author Rod Johnson
*/
public abstract class StaticMethodMatcher implements MethodMatcher {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 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.
@@ -36,10 +36,10 @@ import org.springframework.util.Assert;
public abstract class StaticMethodMatcherPointcutAdvisor extends StaticMethodMatcherPointcut
implements PointcutAdvisor, Ordered, Serializable {
private int order = Integer.MAX_VALUE;
private Advice advice;
private int order = Integer.MAX_VALUE;
/**
* Create a new StaticMethodMatcherPointcutAdvisor,
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,7 +22,6 @@ import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* Simple Pointcut that looks for a specific Java 5 annotation
@@ -46,16 +45,15 @@ public class AnnotationMatchingPointcut implements Pointcut {
* @param classAnnotationType the annotation type to look for at the class level
*/
public AnnotationMatchingPointcut(Class<? extends Annotation> classAnnotationType) {
this.classFilter = new AnnotationClassFilter(classAnnotationType);
this.methodMatcher = MethodMatcher.TRUE;
this(classAnnotationType, false);
}
/**
* Create a new AnnotationMatchingPointcut for the given annotation type.
* @param classAnnotationType the annotation type to look for at the class level
* @param checkInherited whether to explicitly check the superclasses and
* interfaces for the annotation type as well (even if the annotation type
* is not marked as inherited itself)
* @param checkInherited whether to also check the superclasses and interfaces
* as well as meta-annotations for the annotation type
* @see AnnotationClassFilter#AnnotationClassFilter(Class, boolean)
*/
public AnnotationMatchingPointcut(Class<? extends Annotation> classAnnotationType, boolean checkInherited) {
this.classFilter = new AnnotationClassFilter(classAnnotationType, checkInherited);
@@ -109,21 +107,14 @@ public class AnnotationMatchingPointcut implements Pointcut {
if (!(other instanceof AnnotationMatchingPointcut)) {
return false;
}
AnnotationMatchingPointcut that = (AnnotationMatchingPointcut) other;
return ObjectUtils.nullSafeEquals(that.classFilter, this.classFilter) &&
ObjectUtils.nullSafeEquals(that.methodMatcher, this.methodMatcher);
AnnotationMatchingPointcut otherPointcut = (AnnotationMatchingPointcut) other;
return (this.classFilter.equals(otherPointcut.classFilter) &&
this.methodMatcher.equals(otherPointcut.methodMatcher));
}
@Override
public int hashCode() {
int code = 17;
if (this.classFilter != null) {
code = 37 * code + this.classFilter.hashCode();
}
if (this.methodMatcher != null) {
code = 37 * code + this.methodMatcher.hashCode();
}
return code;
return this.classFilter.hashCode() * 37 + this.methodMatcher.hashCode();
}
@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.
@@ -60,7 +60,7 @@ public abstract class AbstractBeanFactoryBasedTargetSource implements TargetSour
private String targetBeanName;
/** Class of the target */
private Class<?> targetClass;
private volatile Class<?> targetClass;
/**
* BeanFactory that owns this TargetSource. We need to hold onto this
@@ -120,21 +120,28 @@ public abstract class AbstractBeanFactoryBasedTargetSource implements TargetSour
@Override
public synchronized Class<?> getTargetClass() {
if (this.targetClass == null && this.beanFactory != null) {
// Determine type of the target bean.
this.targetClass = this.beanFactory.getType(this.targetBeanName);
if (this.targetClass == null) {
if (logger.isTraceEnabled()) {
logger.trace("Getting bean with name '" + this.targetBeanName + "' in order to determine type");
}
Object beanInstance = this.beanFactory.getBean(this.targetBeanName);
if (beanInstance != null) {
this.targetClass = beanInstance.getClass();
}
}
public Class<?> getTargetClass() {
Class<?> targetClass = this.targetClass;
if (targetClass != null) {
return targetClass;
}
synchronized (this) {
// Full check within synchronization, entering the BeanFactory interaction algorithm only once...
targetClass = this.targetClass;
if (targetClass == null && this.beanFactory != null) {
// Determine type of the target bean.
targetClass = this.beanFactory.getType(this.targetBeanName);
if (targetClass == null) {
if (logger.isTraceEnabled()) {
logger.trace("Getting bean with name '" + this.targetBeanName + "' for type determination");
}
Object beanInstance = this.beanFactory.getBean(this.targetBeanName);
targetClass = beanInstance.getClass();
}
this.targetClass = targetClass;
}
return targetClass;
}
return this.targetClass;
}
@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.
@@ -74,8 +74,8 @@ public abstract class AbstractPrototypeBasedTargetSource extends AbstractBeanFac
* @param target the bean instance to destroy
*/
protected void destroyPrototypeInstance(Object target) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Destroying instance of bean '" + getTargetBeanName() + "'");
if (logger.isDebugEnabled()) {
logger.debug("Destroying instance of bean '" + getTargetBeanName() + "'");
}
if (getBeanFactory() instanceof ConfigurableBeanFactory) {
((ConfigurableBeanFactory) getBeanFactory()).destroyBean(getTargetBeanName(), target);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,7 +39,7 @@ import org.springframework.aop.TargetSource;
public abstract class AbstractRefreshableTargetSource implements TargetSource, Refreshable {
/** Logger available to subclasses */
protected Log logger = LogFactory.getLog(getClass());
protected final Log logger = LogFactory.getLog(getClass());
protected Object targetObject;
@@ -44,7 +44,7 @@ import static org.junit.Assert.*;
* @author Ramnivas Laddad
* @since 2.0
*/
public final class MethodInvocationProceedingJoinPointTests {
public class MethodInvocationProceedingJoinPointTests {
@Test
public void testingBindingWithJoinPoint() {
@@ -217,7 +217,7 @@ public final class MethodInvocationProceedingJoinPointTests {
itb.unreliableFileOperation();
}
catch (IOException ex) {
// we don't realy care...
// we don't really care...
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,26 +37,26 @@ import static org.junit.Assert.*;
* @author Juergen Hoeller
* @author Chris Beams
*/
public final class ArgumentBindingTests {
public class ArgumentBindingTests {
@Test(expected=IllegalArgumentException.class)
@Test(expected = IllegalArgumentException.class)
public void testBindingInPointcutUsedByAdvice() {
TestBean tb = new TestBean();
AspectJProxyFactory proxyFactory = new AspectJProxyFactory(tb);
proxyFactory.addAspect(NamedPointcutWithArgs.class);
ITestBean proxiedTestBean = (ITestBean) proxyFactory.getProxy();
proxiedTestBean.setName("Supercalifragalisticexpialidocious"); // should throw
ITestBean proxiedTestBean = proxyFactory.getProxy();
proxiedTestBean.setName("Supercalifragalisticexpialidocious");
}
@Test(expected=IllegalStateException.class)
@Test(expected = IllegalStateException.class)
public void testAnnotationArgumentNameBinding() {
TransactionalBean tb = new TransactionalBean();
AspectJProxyFactory proxyFactory = new AspectJProxyFactory(tb);
proxyFactory.addAspect(PointcutWithAnnotationArgument.class);
ITransactionalBean proxiedTestBean = (ITransactionalBean) proxyFactory.getProxy();
proxiedTestBean.doInTransaction(); // should throw
ITransactionalBean proxiedTestBean = proxyFactory.getProxy();
proxiedTestBean.doInTransaction();
}
@Test
@@ -71,6 +71,7 @@ public final class ArgumentBindingTests {
assertEquals("formal", pnames[0]);
}
public void methodWithOneParam(String aParam) {
}
@@ -100,9 +101,6 @@ public final class ArgumentBindingTests {
}
/**
* @author Juergen Hoeller
*/
@Aspect
class PointcutWithAnnotationArgument {
@@ -115,9 +113,6 @@ class PointcutWithAnnotationArgument {
}
/**
* @author Adrian Colyer
*/
@Aspect
class NamedPointcutWithArgs {
@@ -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.
@@ -47,7 +47,7 @@ public final class ConcurrencyThrottleInterceptorTests {
public void testSerializable() throws Exception {
DerivedTestBean tb = new DerivedTestBean();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setInterfaces(new Class[] {ITestBean.class});
proxyFactory.setInterfaces(ITestBean.class);
ConcurrencyThrottleInterceptor cti = new ConcurrencyThrottleInterceptor();
proxyFactory.addAdvice(cti);
proxyFactory.setTarget(tb);
@@ -75,7 +75,7 @@ public final class ConcurrencyThrottleInterceptorTests {
private void testMultipleThreads(int concurrencyLimit) {
TestBean tb = new TestBean();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setInterfaces(new Class[] {ITestBean.class});
proxyFactory.setInterfaces(ITestBean.class);
ConcurrencyThrottleInterceptor cti = new ConcurrencyThrottleInterceptor();
cti.setConcurrencyLimit(concurrencyLimit);
proxyFactory.addAdvice(cti);
@@ -95,7 +95,7 @@ public final class ConcurrencyThrottleInterceptorTests {
ex.printStackTrace();
}
threads[i] = new ConcurrencyThread(proxy,
i % 2 == 0 ? (Throwable) new OutOfMemoryError() : (Throwable) new IllegalStateException());
i % 2 == 0 ? new OutOfMemoryError() : new IllegalStateException());
threads[i].start();
}
for (int i = 0; i < NR_OF_THREADS; i++) {
@@ -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.
@@ -83,7 +83,7 @@ public final class CustomizableTraceInterceptorTests {
public void testSunnyDayPathLogsCorrectly() throws Throwable {
MethodInvocation methodInvocation = mock(MethodInvocation.class);
given(methodInvocation.getMethod()).willReturn(String.class.getMethod("toString", new Class[]{}));
given(methodInvocation.getMethod()).willReturn(String.class.getMethod("toString"));
given(methodInvocation.getThis()).willReturn(this);
Log log = mock(Log.class);
@@ -101,7 +101,7 @@ public final class CustomizableTraceInterceptorTests {
MethodInvocation methodInvocation = mock(MethodInvocation.class);
IllegalArgumentException exception = new IllegalArgumentException();
given(methodInvocation.getMethod()).willReturn(String.class.getMethod("toString", new Class[]{}));
given(methodInvocation.getMethod()).willReturn(String.class.getMethod("toString"));
given(methodInvocation.getThis()).willReturn(this);
given(methodInvocation.proceed()).willThrow(exception);
@@ -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.
@@ -34,7 +34,7 @@ public final class SimpleTraceInterceptorTests {
@Test
public void testSunnyDayPathLogsCorrectly() throws Throwable {
MethodInvocation mi = mock(MethodInvocation.class);
given(mi.getMethod()).willReturn(String.class.getMethod("toString", new Class[]{}));
given(mi.getMethod()).willReturn(String.class.getMethod("toString"));
given(mi.getThis()).willReturn(this);
Log log = mock(Log.class);
@@ -48,7 +48,7 @@ public final class SimpleTraceInterceptorTests {
@Test
public void testExceptionPathStillLogsCorrectly() throws Throwable {
MethodInvocation mi = mock(MethodInvocation.class);
given(mi.getMethod()).willReturn(String.class.getMethod("toString", new Class[]{}));
given(mi.getMethod()).willReturn(String.class.getMethod("toString"));
given(mi.getThis()).willReturn(this);
IllegalArgumentException exception = new IllegalArgumentException();
given(mi.proceed()).willThrow(exception);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,8 @@
package org.springframework.aop.scope;
import java.util.Arrays;
import org.junit.Test;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
@@ -27,19 +29,24 @@ import static org.springframework.tests.TestResourceUtils.*;
/**
* @author Mark Fisher
* @author Juergen Hoeller
* @author Chris Beams
*/
public final class ScopedProxyAutowireTests {
public class ScopedProxyAutowireTests {
private static final Class<?> CLASS = ScopedProxyAutowireTests.class;
private static final Resource SCOPED_AUTOWIRE_FALSE_CONTEXT =
qualifiedResource(ScopedProxyAutowireTests.class, "scopedAutowireFalse.xml");
private static final Resource SCOPED_AUTOWIRE_TRUE_CONTEXT =
qualifiedResource(ScopedProxyAutowireTests.class, "scopedAutowireTrue.xml");
private static final Resource SCOPED_AUTOWIRE_TRUE_CONTEXT = qualifiedResource(CLASS, "scopedAutowireTrue.xml");
private static final Resource SCOPED_AUTOWIRE_FALSE_CONTEXT = qualifiedResource(CLASS, "scopedAutowireFalse.xml");
@Test
public void testScopedProxyInheritsAutowireCandidateFalse() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(SCOPED_AUTOWIRE_FALSE_CONTEXT);
assertTrue(Arrays.asList(bf.getBeanNamesForType(TestBean.class, false, false)).contains("scoped"));
assertTrue(Arrays.asList(bf.getBeanNamesForType(TestBean.class, true, false)).contains("scoped"));
assertFalse(bf.containsSingleton("scoped"));
TestBean autowired = (TestBean) bf.getBean("autowired");
TestBean unscoped = (TestBean) bf.getBean("unscoped");
assertSame(unscoped, autowired.getChild());
@@ -49,6 +56,9 @@ public final class ScopedProxyAutowireTests {
public void testScopedProxyReplacesAutowireCandidateTrue() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(SCOPED_AUTOWIRE_TRUE_CONTEXT);
assertTrue(Arrays.asList(bf.getBeanNamesForType(TestBean.class, true, false)).contains("scoped"));
assertTrue(Arrays.asList(bf.getBeanNamesForType(TestBean.class, false, false)).contains("scoped"));
assertFalse(bf.containsSingleton("scoped"));
TestBean autowired = (TestBean) bf.getBean("autowired");
TestBean scoped = (TestBean) bf.getBean("scoped");
assertSame(scoped, autowired.getChild());
@@ -1,6 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,27 +28,21 @@ public class NopInterceptor implements MethodInterceptor {
private int count;
/**
* @see org.aopalliance.intercept.MethodInterceptor#invoke(MethodInvocation)
*/
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
increment();
return invocation.proceed();
}
protected void increment() {
this.count++;
}
public int getCount() {
return this.count;
}
protected void increment() {
++count;
}
@Override
public int hashCode() {
return 0;
}
@Override
public boolean equals(Object other) {
@@ -62,5 +55,9 @@ public class NopInterceptor implements MethodInterceptor {
return this.count == ((NopInterceptor) other).count;
}
@Override
public int hashCode() {
return NopInterceptor.class.hashCode();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,22 +28,10 @@ import org.springframework.util.ObjectUtils;
@SuppressWarnings("serial")
public class SerializablePerson implements Person, Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int age;
@Override
public int getAge() {
return age;
}
@Override
public void setAge(int age) {
this.age = age;
}
@Override
public String getName() {
@@ -55,6 +43,16 @@ public class SerializablePerson implements Person, Serializable {
this.name = name;
}
@Override
public int getAge() {
return age;
}
@Override
public void setAge(int age) {
this.age = age;
}
@Override
public Object echo(Object o) throws Throwable {
if (o instanceof Throwable) {
@@ -63,10 +61,6 @@ public class SerializablePerson implements Person, Serializable {
return o;
}
@Override
public int hashCode() {
return 0;
}
@Override
public boolean equals(Object other) {
@@ -77,4 +71,9 @@ public class SerializablePerson implements Person, Serializable {
return p.age == age && ObjectUtils.nullSafeEquals(name, p.name);
}
@Override
public int hashCode() {
return SerializablePerson.class.hashCode();
}
}
@@ -1,6 +1,6 @@
<config xmlns="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<pointcut id="testPointcut" expression="execution(* foo(..)) and within(springbank.dao.AccountDao+)"/>
<pointcut id="testPointcut1" expression="execution(* springbank.dao.AccountDao.foo(..))"/>
@@ -9,4 +9,4 @@
<after method="foo" pointcut-ref="testPointcut"/>
</aspect>
</config>
</config>
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="scoped" class="org.springframework.aop.scope.ScopedProxyAutowireTests$TestBean" autowire-candidate="false">
<aop:scoped-proxy/>
</bean>
<bean id="scoped" class="org.springframework.aop.scope.ScopedProxyAutowireTests$TestBean" scope="prototype" autowire-candidate="false">
<aop:scoped-proxy/>
</bean>
<bean id="unscoped" class="org.springframework.aop.scope.ScopedProxyAutowireTests$TestBean" autowire-candidate="true"/>
<bean id="unscoped" class="org.springframework.aop.scope.ScopedProxyAutowireTests$TestBean" autowire-candidate="true"/>
<bean id="autowired" class="org.springframework.aop.scope.ScopedProxyAutowireTests$TestBean" autowire="byType"/>
<bean id="autowired" class="org.springframework.aop.scope.ScopedProxyAutowireTests$TestBean" autowire="byType"/>
</beans>
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="scoped" class="org.springframework.aop.scope.ScopedProxyAutowireTests$TestBean" autowire-candidate="true">
<aop:scoped-proxy/>
</bean>
<bean id="scoped" class="org.springframework.aop.scope.ScopedProxyAutowireTests$TestBean" scope="singleton" autowire-candidate="true">
<aop:scoped-proxy/>
</bean>
<bean id="unscoped" class="org.springframework.aop.scope.ScopedProxyAutowireTests$TestBean" autowire-candidate="false"/>
<bean id="unscoped" class="org.springframework.aop.scope.ScopedProxyAutowireTests$TestBean" autowire-candidate="false"/>
<bean id="autowired" class="org.springframework.aop.scope.ScopedProxyAutowireTests$TestBean" autowire="byType"/>
<bean id="autowired" class="org.springframework.aop.scope.ScopedProxyAutowireTests$TestBean" autowire="byType"/>
</beans>
+1 -14
View File
@@ -1,5 +1,4 @@
// redefine the compileJava and compileTestJava tasks in order to
// compile sources with ajc instead of javac
// Redefine the compileJava and compileTestJava tasks in order to compile sources with ajc instead of javac
configurations {
rt
@@ -8,22 +7,14 @@ configurations {
ajInpath
}
// exclude spring-aspects as a module within IDEA until IDEA-64446 is resolved
tasks.getByName("idea").onlyIf { false }
tasks.getByName("ideaModule").onlyIf { false }
compileJava {
actions = []
dependsOn configurations.ajc.getTaskDependencyFromProjectDependency(true, "compileJava")
def outputDir = project.sourceSets.main.output.classesDir
inputs.files(project.sourceSets.main.allSource + project.sourceSets.main.compileClasspath)
outputs.dir outputDir
ext.sourceCompatibility = project(":spring-core").compileJava.sourceCompatibility
ext.targetCompatibility = project(":spring-core").compileJava.targetCompatibility
doLast{
// Assemble runtime classpath from folders and JARs that actually exist
def runtimeClasspath = project.files(sourceSets.main.runtimeClasspath.files.findAll({ it.exists() }))
@@ -53,13 +44,9 @@ compileTestJava {
dependsOn jar
def outputDir = project.sourceSets.test.output.classesDir
inputs.files(project.sourceSets.test.allSource + project.sourceSets.test.compileClasspath)
outputs.dir outputDir
ext.sourceCompatibility = project(":spring-core").compileTestJava.sourceCompatibility
ext.targetCompatibility = project(":spring-core").compileTestJava.targetCompatibility
doLast{
// Assemble runtime classpath from folders and JARs that actually exist
def runtimeClasspath = project.files(sourceSets.test.runtimeClasspath.files.findAll({ it.exists() }))
@@ -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.
@@ -34,6 +34,7 @@ import org.springframework.context.annotation.Role;
* @see org.springframework.cache.annotation.CachingConfigurationSelector
*/
@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class AspectJCachingConfiguration extends AbstractCachingConfiguration {
@Bean(name = CacheManagementConfigUtils.CACHE_ASPECT_BEAN_NAME)
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 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.
@@ -34,6 +34,7 @@ import org.springframework.context.annotation.Role;
* @see org.springframework.cache.annotation.CachingConfigurationSelector
*/
@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class AspectJJCacheConfiguration extends AbstractJCacheConfiguration {
@Bean(name = CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME)
@@ -36,7 +36,9 @@ import org.springframework.util.ObjectUtils;
* @author Rod Johnson
* @author Ramnivas Laddad
* @author Sam Brannen
* @deprecated as of Spring 4.3, in favor of a custom aspect for such purposes
*/
@Deprecated
public abstract aspect AbstractMethodMockingControl percflow(mockStaticsTestMethod()) {
private final Expectations expectations = new Expectations();
@@ -59,7 +59,9 @@ import org.aspectj.lang.annotation.SuppressAjWarnings;
* @author Ramnivas Laddad
* @author Sam Brannen
* @see MockStaticEntityMethods
* @deprecated as of Spring 4.3, in favor of a custom aspect for such purposes
*/
@Deprecated
@RequiredTypes("javax.persistence.Entity")
public aspect AnnotationDrivenStaticEntityMockingControl extends AbstractMethodMockingControl {
@@ -29,7 +29,9 @@ import java.lang.annotation.Target;
*
* @author Rod Johnson
* @author Sam Brannen
* @deprecated as of Spring 4.3, in favor of a custom aspect for such purposes
*/
@Deprecated
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MockStaticEntityMethods {
@@ -45,7 +45,7 @@ import org.springframework.transaction.annotation.AnnotationTransactionAttribute
* @see javax.transaction.Transactional
* @see AnnotationTransactionAspect
*/
@RequiredTypes({"javax.transaction.Transactional"})
@RequiredTypes("javax.transaction.Transactional")
public aspect JtaAnnotationTransactionAspect extends AbstractTransactionAspect {
public JtaAnnotationTransactionAspect() {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,55 +18,45 @@ package org.springframework.transaction.aspectj;
import java.lang.reflect.Method;
import org.junit.Before;
import org.junit.Test;
import org.springframework.tests.transaction.CallCountingTransactionManager;
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.interceptor.TransactionAttribute;
import static org.junit.Assert.*;
/**
* @author Rod Johnson
* @author Ramnivas Laddad
* @author Juergen Hoeller
* @author Sam Brannen
*/
@SuppressWarnings("deprecation")
public class TransactionAspectTests extends org.springframework.test.AbstractDependencyInjectionSpringContextTests {
public class TransactionAspectTests {
private CallCountingTransactionManager txManager;
private final CallCountingTransactionManager txManager = new CallCountingTransactionManager();
private TransactionalAnnotationOnlyOnClassWithNoInterface annotationOnlyOnClassWithNoInterface;
private final TransactionalAnnotationOnlyOnClassWithNoInterface annotationOnlyOnClassWithNoInterface =
new TransactionalAnnotationOnlyOnClassWithNoInterface();
private ClassWithProtectedAnnotatedMember beanWithAnnotatedProtectedMethod;
private final ClassWithProtectedAnnotatedMember beanWithAnnotatedProtectedMethod =
new ClassWithProtectedAnnotatedMember();
private ClassWithPrivateAnnotatedMember beanWithAnnotatedPrivateMethod;
private final ClassWithPrivateAnnotatedMember beanWithAnnotatedPrivateMethod =
new ClassWithPrivateAnnotatedMember();
private MethodAnnotationOnClassWithNoInterface methodAnnotationOnly = new MethodAnnotationOnClassWithNoInterface();
private final MethodAnnotationOnClassWithNoInterface methodAnnotationOnly =
new MethodAnnotationOnClassWithNoInterface();
public void setAnnotationOnlyOnClassWithNoInterface(
TransactionalAnnotationOnlyOnClassWithNoInterface annotationOnlyOnClassWithNoInterface) {
this.annotationOnlyOnClassWithNoInterface = annotationOnlyOnClassWithNoInterface;
}
public void setClassWithAnnotatedProtectedMethod(ClassWithProtectedAnnotatedMember aBean) {
this.beanWithAnnotatedProtectedMethod = aBean;
}
public void setClassWithAnnotatedPrivateMethod(ClassWithPrivateAnnotatedMember aBean) {
this.beanWithAnnotatedPrivateMethod = aBean;
}
public void setTransactionAspect(TransactionAspectSupport transactionAspect) {
this.txManager = (CallCountingTransactionManager) transactionAspect.getTransactionManager();
}
@Override
protected String[] getConfigPaths() {
return new String[] { "TransactionAspectTests-context.xml" };
@Before
public void initContext() {
AnnotationTransactionAspect.aspectOf().setTransactionManager(txManager);
}
@Test
public void testCommitOnAnnotatedClass() throws Throwable {
txManager.clear();
assertEquals(0, txManager.begun);
@@ -74,6 +64,7 @@ public class TransactionAspectTests extends org.springframework.test.AbstractDep
assertEquals(1, txManager.commits);
}
@Test
public void testCommitOnAnnotatedProtectedMethod() throws Throwable {
txManager.clear();
assertEquals(0, txManager.begun);
@@ -81,6 +72,7 @@ public class TransactionAspectTests extends org.springframework.test.AbstractDep
assertEquals(1, txManager.commits);
}
@Test
public void testCommitOnAnnotatedPrivateMethod() throws Throwable {
txManager.clear();
assertEquals(0, txManager.begun);
@@ -88,6 +80,7 @@ public class TransactionAspectTests extends org.springframework.test.AbstractDep
assertEquals(1, txManager.commits);
}
@Test
public void testNoCommitOnNonAnnotatedNonPublicMethodInTransactionalType() throws Throwable {
txManager.clear();
assertEquals(0,txManager.begun);
@@ -95,6 +88,7 @@ public class TransactionAspectTests extends org.springframework.test.AbstractDep
assertEquals(0,txManager.begun);
}
@Test
public void testCommitOnAnnotatedMethod() throws Throwable {
txManager.clear();
assertEquals(0, txManager.begun);
@@ -102,6 +96,7 @@ public class TransactionAspectTests extends org.springframework.test.AbstractDep
assertEquals(1, txManager.commits);
}
@Test
public void testNotTransactional() throws Throwable {
txManager.clear();
assertEquals(0, txManager.begun);
@@ -109,6 +104,7 @@ public class TransactionAspectTests extends org.springframework.test.AbstractDep
assertEquals(0, txManager.begun);
}
@Test
public void testDefaultCommitOnAnnotatedClass() throws Throwable {
final Exception ex = new Exception();
try {
@@ -125,6 +121,7 @@ public class TransactionAspectTests extends org.springframework.test.AbstractDep
}
}
@Test
public void testDefaultRollbackOnAnnotatedClass() throws Throwable {
final RuntimeException ex = new RuntimeException();
try {
@@ -141,10 +138,11 @@ public class TransactionAspectTests extends org.springframework.test.AbstractDep
}
}
@Test
public void testDefaultCommitOnSubclassOfAnnotatedClass() throws Throwable {
final Exception ex = new Exception();
try {
testRollback(new TransactionOperationCallback() {
testRollback(new TransactionOperationCallback() {
@Override
public Object performTransactionalOperation() throws Throwable {
return new SubclassOfClassWithTransactionalAnnotation().echo(ex);
@@ -157,6 +155,7 @@ public class TransactionAspectTests extends org.springframework.test.AbstractDep
}
}
@Test
public void testDefaultCommitOnSubclassOfClassWithTransactionalMethodAnnotated() throws Throwable {
final Exception ex = new Exception();
try {
@@ -173,6 +172,7 @@ public class TransactionAspectTests extends org.springframework.test.AbstractDep
}
}
@Test
public void testDefaultCommitOnImplementationOfAnnotatedInterface() throws Throwable {
final Exception ex = new Exception();
testNotTransactional(new TransactionOperationCallback() {
@@ -185,16 +185,19 @@ public class TransactionAspectTests extends org.springframework.test.AbstractDep
/**
* Note: resolution does not occur. Thus we can't make a class transactional if
* it implements a transactionally annotated interface. This behaviour could only
* it implements a transactionally annotated interface. This behavior could only
* be changed in AbstractFallbackTransactionAttributeSource in Spring proper.
* See SPR-14322.
*/
@Test
public void testDoesNotResolveTxAnnotationOnMethodFromClassImplementingAnnotatedInterface() throws Exception {
AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource();
Method m = ImplementsAnnotatedInterface.class.getMethod("echo", Throwable.class);
TransactionAttribute ta = atas.getTransactionAttribute(m, ImplementsAnnotatedInterface.class);
Method method = ImplementsAnnotatedInterface.class.getMethod("echo", Throwable.class);
TransactionAttribute ta = atas.getTransactionAttribute(method, ImplementsAnnotatedInterface.class);
assertNull(ta);
}
@Test
public void testDefaultRollbackOnImplementationOfAnnotatedInterface() throws Throwable {
final Exception rollbackProvokingException = new RuntimeException();
testNotTransactional(new TransactionOperationCallback() {
@@ -237,15 +240,19 @@ public class TransactionAspectTests extends org.springframework.test.AbstractDep
private interface TransactionOperationCallback {
Object performTransactionalOperation() throws Throwable;
}
public static class SubclassOfClassWithTransactionalAnnotation extends TransactionalAnnotationOnlyOnClassWithNoInterface {
}
public static class SubclassOfClassWithTransactionalMethodAnnotation extends MethodAnnotationOnClassWithNoInterface {
}
public static class ImplementsAnnotatedInterface implements ITransactional {
@Override
@@ -257,6 +264,7 @@ public class TransactionAspectTests extends org.springframework.test.AbstractDep
}
}
public static class NotTransactional {
public void noop() {
@@ -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.
@@ -237,6 +237,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
}
Closure beans = new Closure(this) {
@Override
public Object call(Object[] args) {
invokeBeanDefiningClosure((Closure) args[0]);
return null;
@@ -303,7 +304,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
Collection constructorArgs = null;
if (!ObjectUtils.isEmpty(args)) {
int index = args.length;
Object lastArg = args[index-1];
Object lastArg = args[index - 1];
if (lastArg instanceof Closure) {
callable = (Closure) lastArg;
index--;
@@ -380,10 +381,8 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
refName = args[0].toString();
}
boolean parentRef = false;
if (args.length > 1) {
if (args[1] instanceof Boolean) {
parentRef = (Boolean) args[1];
}
if (args.length > 1 && args[1] instanceof Boolean) {
parentRef = (Boolean) args[1];
}
return new RuntimeBeanReference(refName, parentRef);
}
@@ -410,12 +409,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
}
private boolean addDeferredProperty(String property, Object newValue) {
if (newValue instanceof List) {
this.deferredProperties.put(this.currentBeanDefinition.getBeanName() + '.' + property,
new DeferredProperty(this.currentBeanDefinition, property, newValue));
return true;
}
else if (newValue instanceof Map) {
if (newValue instanceof List || newValue instanceof Map) {
this.deferredProperties.put(this.currentBeanDefinition.getBeanName() + '.' + property,
new DeferredProperty(this.currentBeanDefinition, property, newValue));
return true;
@@ -456,14 +450,14 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
* @return the bean definition wrapper
*/
private GroovyBeanDefinitionWrapper invokeBeanDefiningMethod(String beanName, Object[] args) {
boolean hasClosureArgument = args[args.length - 1] instanceof Closure;
boolean hasClosureArgument = (args[args.length - 1] instanceof Closure);
if (args[0] instanceof Class) {
Class<?> beanClass = (args[0] instanceof Class ? (Class) args[0] : args[0].getClass());
Class<?> beanClass = (Class<?>) args[0];
if (args.length >= 1) {
if (hasClosureArgument) {
if (args.length-1 != 1) {
if (args.length - 1 != 1) {
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(
beanName, beanClass, resolveConstructorArguments(args,1,args.length-1));
beanName, beanClass, resolveConstructorArguments(args, 1, args.length - 1));
}
else {
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName, beanClass);
@@ -471,7 +465,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
}
else {
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(
beanName, beanClass, resolveConstructorArguments(args,1,args.length));
beanName, beanClass, resolveConstructorArguments(args, 1, args.length));
}
}
@@ -483,7 +477,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
else if (args[0] instanceof Map) {
// named constructor arguments
if (args.length > 1 && args[1] instanceof Class) {
List constructorArgs = resolveConstructorArguments(args, 2, hasClosureArgument ? args.length-1 : args.length);
List constructorArgs = resolveConstructorArguments(args, 2, hasClosureArgument ? args.length - 1 : args.length);
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName, (Class)args[1], constructorArgs);
Map namedArgs = (Map)args[0];
for (Object o : namedArgs.keySet()) {
@@ -519,18 +513,18 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
this.currentBeanDefinition.getBeanDefinition().setAbstract(true);
}
else {
List constructorArgs = resolveConstructorArguments(args, 0, hasClosureArgument ? args.length-1 : args.length);
List constructorArgs = resolveConstructorArguments(args, 0, hasClosureArgument ? args.length - 1 : args.length);
currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName, null, constructorArgs);
}
if (hasClosureArgument) {
Closure callable = (Closure)args[args.length-1];
Closure callable = (Closure) args[args.length - 1];
callable.setDelegate(this);
callable.setResolveStrategy(Closure.DELEGATE_FIRST);
callable.call(new Object[]{currentBeanDefinition});
callable.call(this.currentBeanDefinition);
}
GroovyBeanDefinitionWrapper beanDefinition = currentBeanDefinition;
GroovyBeanDefinitionWrapper beanDefinition = this.currentBeanDefinition;
this.currentBeanDefinition = null;
beanDefinition.getBeanDefinition().setAttribute(GroovyBeanDefinitionWrapper.class.getName(), beanDefinition);
getRegistry().registerBeanDefinition(beanName, beanDefinition.getBeanDefinition());
@@ -818,14 +812,17 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
return retVal;
}
@Override
public Object invokeMethod(String name, Object args) {
return InvokerHelper.invokeMethod(this.propertyValue, name, args);
}
@Override
public Object getProperty(String name) {
return InvokerHelper.getProperty(this.propertyValue, name);
}
@Override
public void setProperty(String name, Object value) {
InvokerHelper.setProperty(this.propertyValue, name, value);
}
@@ -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.
@@ -162,6 +162,7 @@ class GroovyBeanDefinitionWrapper extends GroovyObjectSupport {
}
@Override
public Object getProperty(String property) {
if (this.definitionWrapper.isReadableProperty(property)) {
return this.definitionWrapper.getPropertyValue(property);
@@ -172,6 +173,7 @@ class GroovyBeanDefinitionWrapper extends GroovyObjectSupport {
return super.getProperty(property);
}
@Override
public void setProperty(String property, Object newValue) {
if (PARENT.equals(property)) {
setParent(newValue);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -55,10 +55,10 @@ import org.springframework.util.StringUtils;
* as String arrays are converted in such a format if the array itself is not
* assignable.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Rob Harrop
* @author Stephane Nicoll
* @author Rod Johnson
* @author Rob Harrop
* @since 4.2
* @see #registerCustomEditor
* @see #setPropertyValues
@@ -94,11 +94,9 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
private String nestedPath = "";
private Object rootObject;
Object rootObject;
/**
* Map with cached nested Accessors: nested path -> Accessor instance.
*/
/** Map with cached nested Accessors: nested path -> Accessor instance */
private Map<String, AbstractNestablePropertyAccessor> nestedPropertyAccessors;
@@ -284,198 +282,212 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
}
}
@SuppressWarnings("unchecked")
protected void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {
String propertyName = tokens.canonicalName;
String actualName = tokens.actualName;
if (tokens.keys != null) {
// Apply indexes and map keys: fetch value for all keys but the last one.
PropertyTokenHolder getterTokens = new PropertyTokenHolder();
getterTokens.canonicalName = tokens.canonicalName;
getterTokens.actualName = tokens.actualName;
getterTokens.keys = new String[tokens.keys.length - 1];
System.arraycopy(tokens.keys, 0, getterTokens.keys, 0, tokens.keys.length - 1);
Object propValue;
processKeyedProperty(tokens, pv);
}
else {
processLocalProperty(tokens, pv);
}
}
@SuppressWarnings("unchecked")
private void processKeyedProperty(PropertyTokenHolder tokens, PropertyValue pv) {
Object propValue = getPropertyHoldingValue(tokens);
String lastKey = tokens.keys[tokens.keys.length - 1];
if (propValue.getClass().isArray()) {
PropertyHandler ph = getLocalPropertyHandler(tokens.actualName);
Class<?> requiredType = propValue.getClass().getComponentType();
int arrayIndex = Integer.parseInt(lastKey);
Object oldValue = null;
try {
propValue = getPropertyValue(getterTokens);
}
catch (NotReadablePropertyException ex) {
throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
"Cannot access indexed value in property referenced " +
"in indexed property path '" + propertyName + "'", ex);
}
// Set value for last key.
String key = tokens.keys[tokens.keys.length - 1];
if (propValue == null) {
// null map value case
if (isAutoGrowNestedPaths()) {
// TODO: cleanup, this is pretty hacky
int lastKeyIndex = tokens.canonicalName.lastIndexOf('[');
getterTokens.canonicalName = tokens.canonicalName.substring(0, lastKeyIndex);
propValue = setDefaultValue(getterTokens);
if (isExtractOldValueForEditor() && arrayIndex < Array.getLength(propValue)) {
oldValue = Array.get(propValue, arrayIndex);
}
else {
throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + propertyName,
"Cannot access indexed value in property referenced " +
"in indexed property path '" + propertyName + "': returned null");
}
}
if (propValue.getClass().isArray()) {
PropertyHandler ph = getLocalPropertyHandler(actualName);
Class<?> requiredType = propValue.getClass().getComponentType();
int arrayIndex = Integer.parseInt(key);
Object oldValue = null;
try {
if (isExtractOldValueForEditor() && arrayIndex < Array.getLength(propValue)) {
oldValue = Array.get(propValue, arrayIndex);
}
Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(),
requiredType, ph.nested(tokens.keys.length));
int length = Array.getLength(propValue);
if (arrayIndex >= length && arrayIndex < this.autoGrowCollectionLimit) {
Class<?> componentType = propValue.getClass().getComponentType();
Object newArray = Array.newInstance(componentType, arrayIndex + 1);
System.arraycopy(propValue, 0, newArray, 0, length);
setPropertyValue(actualName, newArray);
propValue = getPropertyValue(actualName);
}
Array.set(propValue, arrayIndex, convertedValue);
}
catch (IndexOutOfBoundsException ex) {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
"Invalid array index in property path '" + propertyName + "'", ex);
}
}
else if (propValue instanceof List) {
PropertyHandler ph = getPropertyHandler(actualName);
Class<?> requiredType = ph.getCollectionType(tokens.keys.length);
List<Object> list = (List<Object>) propValue;
int index = Integer.parseInt(key);
Object oldValue = null;
if (isExtractOldValueForEditor() && index < list.size()) {
oldValue = list.get(index);
}
Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(),
Object convertedValue = convertIfNecessary(tokens.canonicalName, oldValue, pv.getValue(),
requiredType, ph.nested(tokens.keys.length));
int size = list.size();
if (index >= size && index < this.autoGrowCollectionLimit) {
for (int i = size; i < index; i++) {
try {
list.add(null);
}
catch (NullPointerException ex) {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
"Cannot set element with index " + index + " in List of size " +
size + ", accessed using property path '" + propertyName +
"': List does not support filling up gaps with null elements");
}
}
list.add(convertedValue);
}
else {
try {
list.set(index, convertedValue);
}
catch (IndexOutOfBoundsException ex) {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
"Invalid list index in property path '" + propertyName + "'", ex);
}
int length = Array.getLength(propValue);
if (arrayIndex >= length && arrayIndex < this.autoGrowCollectionLimit) {
Class<?> componentType = propValue.getClass().getComponentType();
Object newArray = Array.newInstance(componentType, arrayIndex + 1);
System.arraycopy(propValue, 0, newArray, 0, length);
setPropertyValue(tokens.actualName, newArray);
propValue = getPropertyValue(tokens.actualName);
}
Array.set(propValue, arrayIndex, convertedValue);
}
else if (propValue instanceof Map) {
PropertyHandler ph = getLocalPropertyHandler(actualName);
Class<?> mapKeyType = ph.getMapKeyType(tokens.keys.length);
Class<?> mapValueType = ph.getMapValueType(tokens.keys.length);
Map<Object, Object> map = (Map<Object, Object>) propValue;
// IMPORTANT: Do not pass full property name in here - property editors
// must not kick in for map keys but rather only for map values.
TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(mapKeyType);
Object convertedMapKey = convertIfNecessary(null, null, key, mapKeyType, typeDescriptor);
Object oldValue = null;
if (isExtractOldValueForEditor()) {
oldValue = map.get(convertedMapKey);
}
// Pass full property name and old value in here, since we want full
// conversion ability for map values.
Object convertedMapValue = convertIfNecessary(propertyName, oldValue, pv.getValue(),
mapValueType, ph.nested(tokens.keys.length));
map.put(convertedMapKey, convertedMapValue);
}
else {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
"Property referenced in indexed property path '" + propertyName +
"' is neither an array nor a List nor a Map; returned value was [" + propValue + "]");
catch (IndexOutOfBoundsException ex) {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,
"Invalid array index in property path '" + tokens.canonicalName + "'", ex);
}
}
else {
PropertyHandler ph = getLocalPropertyHandler(actualName);
if (ph == null || !ph.isWritable()) {
if (pv.isOptional()) {
if (logger.isDebugEnabled()) {
logger.debug("Ignoring optional value for property '" + actualName +
"' - property not found on bean class [" + getRootClass().getName() + "]");
else if (propValue instanceof List) {
PropertyHandler ph = getPropertyHandler(tokens.actualName);
Class<?> requiredType = ph.getCollectionType(tokens.keys.length);
List<Object> list = (List<Object>) propValue;
int index = Integer.parseInt(lastKey);
Object oldValue = null;
if (isExtractOldValueForEditor() && index < list.size()) {
oldValue = list.get(index);
}
Object convertedValue = convertIfNecessary(tokens.canonicalName, oldValue, pv.getValue(),
requiredType, ph.nested(tokens.keys.length));
int size = list.size();
if (index >= size && index < this.autoGrowCollectionLimit) {
for (int i = size; i < index; i++) {
try {
list.add(null);
}
catch (NullPointerException ex) {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,
"Cannot set element with index " + index + " in List of size " +
size + ", accessed using property path '" + tokens.canonicalName +
"': List does not support filling up gaps with null elements");
}
return;
}
else {
throw createNotWritablePropertyException(propertyName);
list.add(convertedValue);
}
else {
try {
list.set(index, convertedValue);
}
catch (IndexOutOfBoundsException ex) {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,
"Invalid list index in property path '" + tokens.canonicalName + "'", ex);
}
}
}
else if (propValue instanceof Map) {
PropertyHandler ph = getLocalPropertyHandler(tokens.actualName);
Class<?> mapKeyType = ph.getMapKeyType(tokens.keys.length);
Class<?> mapValueType = ph.getMapValueType(tokens.keys.length);
Map<Object, Object> map = (Map<Object, Object>) propValue;
// IMPORTANT: Do not pass full property name in here - property editors
// must not kick in for map keys but rather only for map values.
TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(mapKeyType);
Object convertedMapKey = convertIfNecessary(null, null, lastKey, mapKeyType, typeDescriptor);
Object oldValue = null;
try {
Object originalValue = pv.getValue();
Object valueToApply = originalValue;
if (!Boolean.FALSE.equals(pv.conversionNecessary)) {
if (pv.isConverted()) {
valueToApply = pv.getConvertedValue();
}
else {
if (isExtractOldValueForEditor() && ph.isReadable()) {
try {
oldValue = ph.getValue();
if (isExtractOldValueForEditor()) {
oldValue = map.get(convertedMapKey);
}
// Pass full property name and old value in here, since we want full
// conversion ability for map values.
Object convertedMapValue = convertIfNecessary(tokens.canonicalName, oldValue, pv.getValue(),
mapValueType, ph.nested(tokens.keys.length));
map.put(convertedMapKey, convertedMapValue);
}
else {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,
"Property referenced in indexed property path '" + tokens.canonicalName +
"' is neither an array nor a List nor a Map; returned value was [" + propValue + "]");
}
}
private Object getPropertyHoldingValue(PropertyTokenHolder tokens) {
// Apply indexes and map keys: fetch value for all keys but the last one.
PropertyTokenHolder getterTokens = new PropertyTokenHolder();
getterTokens.canonicalName = tokens.canonicalName;
getterTokens.actualName = tokens.actualName;
getterTokens.keys = new String[tokens.keys.length - 1];
System.arraycopy(tokens.keys, 0, getterTokens.keys, 0, tokens.keys.length - 1);
Object propValue;
try {
propValue = getPropertyValue(getterTokens);
}
catch (NotReadablePropertyException ex) {
throw new NotWritablePropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,
"Cannot access indexed value in property referenced " +
"in indexed property path '" + tokens.canonicalName + "'", ex);
}
if (propValue == null) {
// null map value case
if (isAutoGrowNestedPaths()) {
int lastKeyIndex = tokens.canonicalName.lastIndexOf('[');
getterTokens.canonicalName = tokens.canonicalName.substring(0, lastKeyIndex);
propValue = setDefaultValue(getterTokens);
}
else {
throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + tokens.canonicalName,
"Cannot access indexed value in property referenced " +
"in indexed property path '" + tokens.canonicalName + "': returned null");
}
}
return propValue;
}
private void processLocalProperty(PropertyTokenHolder tokens, PropertyValue pv) {
PropertyHandler ph = getLocalPropertyHandler(tokens.actualName);
if (ph == null || !ph.isWritable()) {
if (pv.isOptional()) {
if (logger.isDebugEnabled()) {
logger.debug("Ignoring optional value for property '" + tokens.actualName +
"' - property not found on bean class [" + getRootClass().getName() + "]");
}
return;
}
else {
throw createNotWritablePropertyException(tokens.canonicalName);
}
}
Object oldValue = null;
try {
Object originalValue = pv.getValue();
Object valueToApply = originalValue;
if (!Boolean.FALSE.equals(pv.conversionNecessary)) {
if (pv.isConverted()) {
valueToApply = pv.getConvertedValue();
}
else {
if (isExtractOldValueForEditor() && ph.isReadable()) {
try {
oldValue = ph.getValue();
}
catch (Exception ex) {
if (ex instanceof PrivilegedActionException) {
ex = ((PrivilegedActionException) ex).getException();
}
catch (Exception ex) {
if (ex instanceof PrivilegedActionException) {
ex = ((PrivilegedActionException) ex).getException();
}
if (logger.isDebugEnabled()) {
logger.debug("Could not read previous value of property '" +
this.nestedPath + propertyName + "'", ex);
}
if (logger.isDebugEnabled()) {
logger.debug("Could not read previous value of property '" +
this.nestedPath + tokens.canonicalName + "'", ex);
}
}
valueToApply = convertForProperty(
propertyName, oldValue, originalValue, ph.toTypeDescriptor());
}
pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
valueToApply = convertForProperty(
tokens.canonicalName, oldValue, originalValue, ph.toTypeDescriptor());
}
ph.setValue(this.wrappedObject, valueToApply);
pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
}
catch (TypeMismatchException ex) {
throw ex;
ph.setValue(this.wrappedObject, valueToApply);
}
catch (TypeMismatchException ex) {
throw ex;
}
catch (InvocationTargetException ex) {
PropertyChangeEvent propertyChangeEvent = new PropertyChangeEvent(
this.rootObject, this.nestedPath + tokens.canonicalName, oldValue, pv.getValue());
if (ex.getTargetException() instanceof ClassCastException) {
throw new TypeMismatchException(propertyChangeEvent, ph.getPropertyType(), ex.getTargetException());
}
catch (InvocationTargetException ex) {
PropertyChangeEvent propertyChangeEvent =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
if (ex.getTargetException() instanceof ClassCastException) {
throw new TypeMismatchException(propertyChangeEvent, ph.getPropertyType(), ex.getTargetException());
}
else {
Throwable cause = ex.getTargetException();
if (cause instanceof UndeclaredThrowableException) {
// May happen e.g. with Groovy-generated methods
cause = cause.getCause();
}
throw new MethodInvocationException(propertyChangeEvent, cause);
else {
Throwable cause = ex.getTargetException();
if (cause instanceof UndeclaredThrowableException) {
// May happen e.g. with Groovy-generated methods
cause = cause.getCause();
}
throw new MethodInvocationException(propertyChangeEvent, cause);
}
catch (Exception ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
throw new MethodInvocationException(pce, ex);
}
}
catch (Exception ex) {
PropertyChangeEvent pce = new PropertyChangeEvent(
this.rootObject, this.nestedPath + tokens.canonicalName, oldValue, pv.getValue());
throw new MethodInvocationException(pce, ex);
}
}
@@ -590,7 +602,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, newValue);
throw new ConversionNotSupportedException(pce, requiredType, ex);
}
catch (Throwable ex) {
catch (IllegalArgumentException ex) {
PropertyChangeEvent pce =
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, newValue);
throw new TypeMismatchException(pce, requiredType, ex);
@@ -914,11 +926,9 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
return BeanUtils.instantiate(type);
}
}
catch (Exception ex) {
// TODO: Root cause exception context is lost here; just exception message preserved.
// Should we throw another exception type that preserves context instead?
catch (Throwable ex) {
throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + name,
"Could not instantiate property type [" + type.getName() + "] to auto-grow nested property path: " + ex);
"Could not instantiate property type [" + type.getName() + "] to auto-grow nested property path", ex);
}
}
@@ -975,9 +985,6 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
}
/**
* Handle a given property.
*/
protected abstract static class PropertyHandler {
private final Class<?> propertyType;
@@ -148,7 +148,7 @@ public abstract class AbstractPropertyAccessor extends TypeConverterSupport impl
* @throws InvalidPropertyException if there is no such property or
* if the property isn't writable
* @throws PropertyAccessException if the property was valid but the
* accessor method failed or a type mismatch occured
* accessor method failed or a type mismatch occurred
*/
@Override
public abstract void setPropertyValue(String propertyName, Object value) throws BeansException;

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