Compare commits

..
Author SHA1 Message Date
Spring Buildmaster 51c9d3e9ac Release version 3.2.18.RELEASE 2016-12-21 18:42:08 +00:00
Juergen Hoeller e57047adf8 Remove outdated JasperReports tests (failing due to missing font on CI server) 2016-12-21 17:37:34 +01:00
Stephane Nicoll f85be8ebef Upgrade to Gradle 2.5
Issue: SPR-15039
2016-12-21 17:04:06 +01:00
Stephane Nicoll f22c669f45 Update changelog for 3.2.18.RELEASE 2016-12-21 15:37:31 +01:00
Brian Clozel a7dc48534e Normalize resource URL in ResourceServlet
Issue: SPR-14946
2016-12-21 10:42:41 +01:00
Juergen Hoeller bd282e632f Polishing
(cherry picked from commit 6e5b873)
2016-12-20 20:40:20 +01:00
Juergen Hoeller 6bdc5bfc08 SpEL docs: supported literals, null comparisons
Issue: SPR-14361
Issue: SPR-14987
2016-12-19 17:56:32 +01:00
Juergen Hoeller 8c26717bdc MBeanExporter silently ignores null beans
Issue: SPR-15031
(cherry picked from commit e9def51)
2016-12-19 17:56:04 +01:00
Juergen Hoeller 6075c81371 Consistent DeferredResultHandler invocation outside of result lock
Issue: SPR-14978
(cherry picked from commit 86614af)
2016-12-19 17:55:59 +01:00
Juergen Hoeller f473392a42 Polishing 2016-10-31 21:57:23 +01:00
Juergen Hoeller 1e2b8aba76 ObjectToObjectConverter properly handles constructors on non-public classes
Issue: SPR-14304
2016-10-31 21:54:26 +01:00
Juergen Hoeller f6024c23ca No external locking for singleton advice/aspect beans
Issue: SPR-14324
(cherry picked from commit 6b7f3fd)
2016-10-31 21:53:18 +01:00
Juergen Hoeller 703b3b1524 StringUtils.parseLocaleString accepts Java 7 variants
Issue: SPR-14718
(cherry picked from commit 818c72a)
2016-09-16 11:16:08 +02:00
Juergen Hoeller cfd16f9c94 ModelAndViewResolver declares handlerType as Class<?>
Issue: SPR-7860
2016-09-13 23:14:33 +02:00
Juergen Hoeller 70f2736c6c Polishing
(cherry picked from commit b344c92)
2016-09-13 23:13:04 +02:00
Juergen Hoeller a5070d562c Correct ISO DateTime example
Issue: SPR-14675
(cherry picked from commit 68332bf)
2016-09-13 23:12:56 +02:00
Juergen Hoeller 5fe608d098 PropertyValue stores source object in common superclass field
Issue: SPR-8337
(cherry picked from commit 53dc996)
2016-09-13 23:12:39 +02:00
Juergen Hoeller 71fd621a1b Polishing
(cherry picked from commit 96f1a0e)
2016-08-18 11:30:10 +02:00
Juergen Hoeller 1295f62319 Polishing 2016-08-17 21:39:24 +02:00
Juergen Hoeller b9a2d0af98 Polishing 2016-08-17 20:43:41 +02:00
Juergen Hoeller 52f21bdf54 Polishing
(cherry picked from commit 22ca7ac)
2016-08-17 20:43:27 +02:00
Juergen Hoeller 3185f67b43 Avoid stack overflow in case of chained factory-bean references to FactoryBean class
Issue: SPR-14551
2016-08-12 00:02:03 +02:00
Juergen Hoeller 9520a593bd Polishing 2016-08-09 12:59:54 +02:00
Juergen Hoeller 6924f00f8c Polishing 2016-08-09 12:12:42 +02:00
Juergen Hoeller e8562bb3af LinkedCaseInsensitiveMap properly overrides HashMap.clone()
Issue: SPR-14509
(cherry picked from commit dadd2c3)
2016-07-25 15:29:46 +02:00
Juergen Hoeller a4b5425108 ResourcePatternUtils.getResourcePatternResolver actually accepts null argument
Issue: SPR-14500
(cherry picked from commit f1fc74c)
2016-07-25 15:29:23 +02:00
Juergen Hoeller 74b4dd0a40 Polishing
(cherry picked from commit b5127dc)
2016-07-20 23:12:06 +02:00
Juergen Hoeller 9ec50a278e Javadoc fixes
(cherry picked from commit 392f9c8)
2016-07-15 23:10:20 +02:00
Juergen Hoeller d3c0e75b95 Polishing 2016-07-15 18:02:26 +02:00
Juergen Hoeller 9be54047e9 CronSequenceGenerator prevents stack overflow in case of inverted range
Issue: SPR-14462
(cherry picked from commit 44152ce)
2016-07-15 17:48:16 +02:00
Juergen Hoeller cb64dd1583 StandardTypeConverter initializes default ConversionService against volatile field
Issue: SPR-14465
(cherry picked from commit 97d73eb)
2016-07-15 17:48:07 +02:00
Stephane Nicoll c38381a54d Upgrade copyright 2016-07-04 12:48:08 +02:00
Juergen Hoeller 51a557b885 Polishing
(cherry picked from commit dd7ddc0)
2016-06-29 15:43:15 +02:00
Rossen Stoyanchev fc37824bc0 Improve static resource path check
(cherry picked from commit 2697425)
2016-06-29 15:41:33 +02:00
Juergen Hoeller 2b9c527d31 Fixed ambiguous sentence in conditional cache documentation
Issue: SPR-14399
2016-06-29 15:37:49 +02:00
Juergen Hoeller 14ab9800ff ObjectUtils.nullSafeEquals allows for JVM method inlining (through reducing its bytecode size)
Issue: SPR-14349
(cherry picked from commit 71df9ce)
2016-06-29 15:20:39 +02:00
Juergen Hoeller a1c09877d9 Avoid potential deadlock in AbstractBeanFactoryPointcutAdvisor
Issue: SPR-14388
(cherry picked from commit 0d3a22c)
2016-06-29 15:20:34 +02:00
Juergen Hoeller 0b8822fab4 Avoid double getFlushMode call 2016-06-04 11:53:06 +02:00
Juergen Hoeller 49ae46d7e4 For attribute is not actually required
Issue: SPR-14287
(cherry picked from commit dacc31e)
2016-06-04 11:52:47 +02:00
Juergen Hoeller 7da129539f @Bean's "autowire" attribute does not affect annotation-driven autowiring
Issue: SPR-14282
(cherry picked from commit 98eaf05)
2016-06-04 11:52:34 +02:00
Spring Buildmaster 6009e03a7f Next Development Version 2016-05-06 10:23:55 +00:00
Stephane Nicoll 2e90a1ccdc Update changelog for 3.2.17.RELEASE 2016-05-06 11:47:00 +02:00
Juergen Hoeller 25cf96f6df AbstractRequestLoggingFilter ignores non-available query string
Issue: SPR-14244
(cherry picked from commit 0f2bc3f)
2016-05-04 18:48:54 +02:00
Juergen Hoeller d6a4981a92 Polishing
(cherry picked from commit 1e491f1)
2016-05-04 18:48:15 +02:00
Juergen Hoeller 07db535b37 Polishing 2016-05-04 09:25:00 +02:00
Juergen Hoeller 5cbe90b2cd Explicit note on Java deserialization 2016-05-04 09:24:53 +02:00
Juergen Hoeller 7de8f4f584 LazySingletonAspectInstanceFactoryDecorator uses shared singleton mutex
Issue: SPR-14241
2016-05-04 09:24:39 +02:00
Rossen Stoyanchev cf39078fbb Backport MVC Java config path-related config options
Issue: SPR-14186
2016-04-21 13:50:03 -04:00
Juergen Hoeller 3d6b0ca5be SpringCacheAnnotationParser properly accepts empty @Caching annotation
Issue: SPR-14162
2016-04-13 13:25:29 +02:00
Juergen Hoeller a8418d3bcd Fixed XML example for setup of scheduled tasks
Issue: SPR-14145
(cherry picked from commit 550a320)
2016-04-11 22:12:18 +02:00
Juergen Hoeller dc20a32ded Backported reference documentation fixes
Issue: SPR-13832
Issue: SPR-14003
2016-04-08 22:30:56 +02:00
Rossen Stoyanchev ac5b9c7bd6 Fix javadoc issue in ResponseEntityExceptionHandler
Issue: SPR-13869
(cherry picked from commit 73df50d)
2016-04-08 22:30:56 +02:00
Juergen Hoeller 7c998a70bc Quartz ResourceLoaderClassLoadHelper explicitly falls back to classpath lookup
Issue: SPR-13706
(cherry picked from commit 51f356f)
2016-04-08 22:30:56 +02:00
Stephane Nicoll 8adff1bd70 Support Quartz trigger without JobDetail
This commit allows to create a Quartz trigger implementation via
either `CronTriggerFactoryBean` or `SimpleTriggerFactoryBean` even if no
job detail is provided.

Issue: SPR-13604
(cherry picked from commit 2970065)
2016-04-08 22:30:56 +02:00
Juergen Hoeller fe76f4084a RequestHeaderMapMethodArgumentResolver defensively checks for non-existing header values
Issue: SPR-14091
(cherry picked from commit 8f6ede5)
2016-04-08 22:30:56 +02:00
Rossen Stoyanchev 9e3bb1e26f Ensure RedirectModel is initialized
This commit fixes an old bug in ModelAndViewContainer where getModel
returns a new ModelMap instance that isn't saved and re-used.

Issue: SPR-14045
(cherry picked from commit d7062f6)
2016-04-08 22:30:56 +02:00
Juergen Hoeller c2eb5e1c1c Bsh/GroovyScriptFactory reset script cache in case of compilation error
Issue: SPR-14007
(cherry picked from commit 05ab769)
2016-04-08 22:30:56 +02:00
Juergen Hoeller 4fe386d572 TimerScheduledFuture correctly calculates getDelay result
Issue: SPR-13977
(cherry picked from commit 97b0177)
2016-04-08 22:30:56 +02:00
Juergen Hoeller ad103016eb AbstractMarshaller defensively uses DocumentBuilderFactory within synchronized block
Issue: SPR-13935
(cherry picked from commit 5047e90)
2016-04-08 22:30:56 +02:00
Juergen Hoeller 512d1263f2 ReflectiveMethodResolver lets local static methods override java.lang.Class methods
Issue: SPR-13918
(cherry picked from commit cf3e460)
2016-04-08 22:30:56 +02:00
Rossen Stoyanchev d11b9577d5 Fix NPE in InvocableHandlerMethod
Issue: SPR-13917
(cherry picked from commit b1a46cc)
2016-04-08 22:30:56 +02:00
Ian Chan 1ea9dd0579 Catch RejectedExecutionException in WebAsyncManager
Issue: SPR-13836
(cherry picked from commit 29692fc)
2016-04-08 22:30:56 +02:00
Rossen Stoyanchev 9d5b6430c4 Remove section on spring-framework-contrib group 2016-04-08 15:45:13 -04:00
Spring Buildmaster f93c520ffe Next Development Version 2015-12-17 05:08:23 -08:00
Stephane Nicoll 368773d3bb Update changelog for 3.2.16.RELEASE 2015-12-17 13:22:03 +01:00
Juergen Hoeller 12eb893e5f Polishing (backported from 4.1.x) 2015-12-09 17:10:34 +01:00
Juergen Hoeller c0e5d00e56 Jdbc4SqlXmlHandler returns null as documented (instead of throwing NPE)
Issue: SPR-13782
(cherry picked from commit 78dad4c)
2015-12-09 17:08:20 +01:00
Juergen Hoeller 73823151bf Polishing 2015-12-07 21:05:07 +01:00
Juergen Hoeller a385153e8c StatementCreatorUtils detects Microsoft SQL Server driver 4.0 as well
Issue: SPR-13772
(cherry picked from commit c2fed6e)
2015-12-07 21:04:11 +01:00
Juergen Hoeller f7031dfb10 Javadoc fixes
Issue: SPR-13765
(cherry picked from commit 242acda)
2015-12-07 21:03:29 +01:00
Juergen Hoeller 7bc04dcd5d Avoid instantiation of non-selected beans in BeanFactoryAnnotationUtils.qualifiedBeanOfType
Issue: SPR-13741
(cherry picked from commit 8ed2c47)
2015-12-03 13:07:48 +01:00
Juergen Hoeller 8890d3190a Upgrade to Hibernate 4.2.21 2015-11-15 13:39:49 +01:00
Juergen Hoeller 88be06e152 Fixed test class name 2015-11-15 13:39:17 +01:00
Juergen Hoeller dac8c9e0f6 Fixed code examples in reference documentation
Issue: SPR-10474
2015-11-15 13:38:55 +01:00
Juergen Hoeller 03585f2e4e Reduced warn log entry without stacktrace for startup exceptions
Also, AbstractApplicationContext.isRunning avoids IllegalStateException now.

Issue: SPR-13663
Issue: SPR-13667
(cherry picked from commit 5d6aab3)
2015-11-15 13:37:19 +01:00
Juergen Hoeller 8d7d4cecf8 CommonsMultipartFile removes mixed separator paths from original filename
Issue: SPR-13662
(cherry picked from commit df49b11)
2015-11-15 13:36:58 +01:00
Juergen Hoeller 2ea69c37c6 Avoid NPE for anonymous SqlParameter in CallMetaDataContext
Issue: SPR-13628
(cherry picked from commit d1f5ee2)
2015-11-15 13:36:37 +01:00
Juergen Hoeller d42cc149db Declared JDBC operation compiled flag as volatile
Issue: SPR-13617
(cherry picked from commit 0f4e4fc)
2015-11-15 13:36:12 +01:00
Rossen Stoyanchev 86ba7476cb Fix failing tests 2015-11-11 18:06:03 -05:00
Rossen Stoyanchev 1489e29d0c Switch "attachment" to "inline" on Content-Disposition
Issue: SPR-13587, SPR-13643
2015-11-11 17:49:58 -05:00
Rossen Stoyanchev f2e4da3dac Whitelist extension if present in the request mapping
We know skip the Content-Disposition header for any extension if the
chosen request mapping explicitly contains the URl extension.

Issue: SPR-13629
2015-11-06 13:01:34 -05:00
Rossen Stoyanchev 6a9329cb76 No Content-Disposition if HTML in the request mapping
Issue: SPR-13629
2015-11-02 13:21:59 -05:00
Spring Buildmaster ac5c904335 Next Development Version 2015-10-15 01:41:28 -07:00
Stephane Nicoll fb4408c779 Update changelog for 3.2.15.RELEASE 2015-10-15 09:45:27 +02:00
Stephane Nicoll 51e8aed41f Add .idea to gitignore 2015-10-15 09:33:21 +02:00
Rossen Stoyanchev 03f547eb98 Protect against RFD exploits
Issue: SPR-13548
2015-10-15 09:32:32 +02:00
Juergen Hoeller daada71c36 Polishing 2015-10-14 14:37:13 +02:00
Juergen Hoeller ef4c978c25 Upgrade to Hibernate 4.2.20 2015-10-14 14:36:24 +02:00
Juergen Hoeller 8a8225925e Clarified that getBody() never returns null
As the only place that historically differed, HttpComponents(Async)ClientHttpResponse returns an empty stream instead of null now.

Issue: SPR-13563
(cherry picked from commit ca60d79)
2015-10-14 14:00:37 +02:00
Juergen Hoeller 6c138d3981 Reliable null value handling in ConcurrentMapCache, GuavaCache, JCacheCache
Issue: SPR-13553
(cherry picked from commit de93290)
2015-10-14 14:00:02 +02:00
Juergen Hoeller bb8a12ff78 Fixed ContentNegotiationManager reference in MVC docs
Issue: SPR-13558
2015-10-14 13:59:40 +02:00
Juergen Hoeller 2b3d1bef10 Portlet MVC documentation consistently refers to Portlet 2.0 spec (JSR-286)
Issue: SPR-13513
2015-10-14 13:59:18 +02:00
Juergen Hoeller 51a0237e0a AbstractEmbeddedDatabaseConfigurer explicitly closes JDBC Connection on shutdown
Issue: SPR-13474
(cherry picked from commit aa0f117)
2015-10-14 13:59:06 +02:00
Juergen Hoeller 73a2407545 DeferredResult accessors based on volatile fields for proper visibility
Issue: SPR-13451
(cherry picked from commit 045016e)
2015-10-14 13:58:49 +02:00
Juergen Hoeller b15da37891 Removed misleading note on readonly and disabled flags in spring-form.tld
Issue: SPR-13397
(cherry picked from commit c4a9abb)
2015-10-14 13:58:15 +02:00
Juergen Hoeller eb5b147364 Avoid ambiguous property warning for methods with multiple parameters
Issue: SPR-13349
(cherry picked from commit 42d5780)
2015-10-14 13:58:00 +02:00
Juergen Hoeller 7491efa2c8 Clarify acknowledge mode semantics and transaction recommendations
Issue: SPR-13278
(cherry picked from commit 4012b4d)
2015-10-14 13:57:42 +02:00
Juergen Hoeller d2447ce523 AbstractEnvironment defensively synchronizes access to activeProfiles and defaultProfiles
Issue: SPR-13213
(cherry picked from commit af5f4e6)
2015-10-14 13:57:03 +02:00
Spring Buildmaster 30a55d73db Next Development Version 2015-06-30 10:36:18 -07:00
Rossen Stoyanchev d875772103 Polish tests 2015-06-30 12:00:12 -04:00
Rossen Stoyanchev 0d394a02f3 Fix test check 2015-06-30 10:00:12 -04:00
Stephane Nicoll d996a0988b Upgrade changelog 2015-06-30 06:19:41 -07:00
Rossen Stoyanchev 5a711c05ec Disable DTD when parsing untrusted XML input
Issue: SPR-13136
2015-06-30 07:59:00 -04:00
Juergen Hoeller 1e42464c22 Polishing 2015-06-17 15:50:19 +02:00
Juergen Hoeller 896f0d91f9 AspectJExpressionPointcut defensively catches exceptions thrown from ShadowMatch.matchesJoinPoint
Issue: SPR-13102
(cherry picked from commit 84ae28b)
2015-06-17 15:50:10 +02:00
Juergen Hoeller 50eef1b979 Upgrade to ASM 5.0.4 (and Hibernate 4.2.19)
Issue: SPR-13039
2015-05-22 17:55:24 +02:00
Juergen Hoeller d5de3867ca Polishing
(cherry picked from commit 3c6f1f8)
2015-05-22 17:50:13 +02:00
Juergen Hoeller a64dcc2a31 Message listener containers only call Session.recover() in client acknowledge mode
Issue: SPR-13052
(cherry picked from commit c111bd7)
2015-05-22 17:38:13 +02:00
Juergen Hoeller e5ccdfb029 Polishing
(cherry picked from commit ce4e795)
2015-05-11 20:12:46 +02:00
Juergen Hoeller adb54b2c69 Backported DispatcherServlet and ServletContextResourcePatternResolver refinements
Issue: SPR-13011
2015-05-11 19:58:36 +02:00
Juergen Hoeller eb6368ca3f CustomBooleanEditor avoids potential NPE in case of allowEmpty=false
Issue: SPR-13010
(cherry picked from commit 0cd7fed)
2015-05-11 19:58:20 +02:00
Juergen Hoeller ed9769a11b Avoid infinite loop in PatternMatchUtils
Issue: SPR-12971
(cherry picked from commit 8e074b6)
2015-05-11 19:58:11 +02:00
Juergen Hoeller b5a56ca3a9 CronSequenceGenerator explicitly rejects invalid incrementer delta
Issue: SPR-12871
(cherry picked from commit 50f4977)
2015-05-11 19:57:25 +02:00
Juergen Hoeller dd73848e15 BeanWrapperImpl.setPropertyValue throws InvalidPropertyException with correct property value for nested collection case
Issue: SPR-12866
(cherry picked from commit d506767)
2015-05-11 19:56:19 +02:00
Juergen Hoeller 64a039402a Clarification: Lifecycle does not imply auto-startup semantics
Issue: SPR-12855
(cherry picked from commit e9e2b73)
2015-05-11 19:55:21 +02:00
Sam Brannen e748cf17d9 Eclipse project deps come after third-party libs
This commit is a backport of SPR-11836.

Prior to this commit, the ordering of classpath entries in the
generated Eclipse .classpath files did not align with the intended
dependency management configured in the Gradle build. Specifically,
project dependencies often came before dependencies on third-party
libraries required for the given project, causing the project not to
compile in Eclipse.

This commit fixes this issue by introducing new functionality in the
ide.gradle script that moves all project dependencies to the end of the
generated classpath.

Issue: SPR-12947, SPR-11836
2015-04-24 21:23:00 +02:00
Juergen Hoeller 3e2491c058 Polishing 2015-03-23 22:43:49 +01:00
Juergen Hoeller e51da28897 Polishing
Issue: SPR-12803
2015-03-11 18:59:32 +01:00
Juergen Hoeller e7cc19537d ReflectiveMethodResolver reliably prefers direct matches over vararg methods
Issue: SPR-12803
2015-03-11 18:58:39 +01:00
Juergen Hoeller 474862a7c9 StandardMultipartFile declares itself as Serializable now
Issue: SPR-12795
(cherry picked from commit 5ba7b89)
2015-03-10 15:30:16 +01:00
Juergen Hoeller 0920266b33 PropertyResourceConfigurerTests accepts "." in operating system name
Issue: SPR-12794
(cherry picked from commit 6fe85c2)
2015-03-10 15:29:44 +01:00
Juergen Hoeller de9c5a8c4d Dependency updates for spring-oxm generation tasks
(cherry picked from commit ebe45cf)
2015-03-06 23:48:20 +01:00
Juergen Hoeller d879bad248 Polishing
(cherry picked from commit 7ed7f98)
2015-03-06 23:47:54 +01:00
Juergen Hoeller ff76be2d16 Converter interface explicitly documents null values
Issue: SPR-12780
(cherry picked from commit 5f30575)
2015-03-06 19:30:05 +01:00
Juergen Hoeller e5207e6231 Polishing 2015-03-02 21:17:16 +01:00
Juergen Hoeller 1c10861a92 Revised documentation on AUTO_ACKNOWLEDGE behavior
Issue: SPR-12705
(cherry picked from commit 91c47a9)
2015-03-02 20:25:10 +01:00
Sam Brannen 1f9bc50c3e Include charset in EncodedResource.equals()
Prior to this commit, the implementation of equals() in EncodedResource
was based solely on the resource and encoding. Thus, if a Charset were
specified instead of an encoding, invocations of equals() would not
work as expected.

This commit addresses this issue by including the charset in the
implementation of equals() and introducing corresponding tests in a new
EncodedResourceTests class. Furthermore, this commit makes
EncodedResource immutable and updates all Javadoc to reflect support
for the encoding and charset properties.

Issue: SPR-12767
(cherry picked from commit 93c70b7440)
2015-02-28 18:01:24 +01:00
Brian Clozel 2d3fe96cd6 Allow file locations for resource handling
Prior to this change, location checks for serving resources would append
`/` to the location path it didn't already have one.

This commit makes sure not to append a `/` if the provided location is
actually a file.

Issue: SPR-12747
2015-02-27 19:12:01 +01:00
Juergen Hoeller 9b26e4f1ad Avoid potential deadlocks between event multicaster and singleton registry through shared lock
Issue: SPR-12739
(cherry picked from commit 772552b)
2015-02-26 21:08:49 +01:00
Juergen Hoeller 9a7871fb70 Consistent validation logic
Issue: SPR-12655
2015-02-20 00:20:07 +01:00
Juergen Hoeller 80128f1992 Polishing 2015-02-19 22:47:26 +01:00
Juergen Hoeller 186fef6808 Revised validation javadoc
Issue: SPR-12655
2015-02-19 22:46:29 +01:00
Juergen Hoeller 3f8d48eb1a Correct reference to executeAndReturnKey method
Issue: SPR-12639
2015-02-18 20:46:04 +01:00
Juergen Hoeller 3ed24bca20 ServletUriComponentsBuilder.java avoids NPE on scheme check
Issue: SPR-12723
(cherry picked from commit 61cc3b5)
2015-02-18 20:44:50 +01:00
Juergen Hoeller f8a8ecd8fe ScheduledAnnotationBeanPostProcessor uses target class as cache key in case of proxy
Issue: SPR-12709
(cherry picked from commit 1273c90)
2015-02-18 20:41:53 +01:00
Spring Buildmaster 16df002de7 Next Development Version 2014-12-30 08:23:52 -08:00
Stephane Nicoll 840ffc5ec4 Update changelog for 3.2.13 2014-12-30 16:49:14 +01:00
Stephane Nicoll 64e79ba692 Use hasLength rather than hasText 2014-12-30 15:39:48 +01:00
Stephane Nicoll 4bcf92f176 Restore JDK 5 compatiblity 2014-12-30 15:34:35 +01:00
Juergen Hoeller 75a9c45865 Polishing
Issue: SPR-12502
(cherry picked from commit 26845f6)
2014-12-30 10:13:03 +01:00
Juergen Hoeller 62a6c3733d Polishing
(cherry picked from commit e9d24d5)
2014-12-29 20:06:57 +01:00
Juergen Hoeller e353af65d2 HandlerExecutionChain prevents re-adding the interceptors array to the list (and declares varargs now)
Issue: SPR-12566
(cherry picked from commit 37713ae)
2014-12-29 20:05:04 +01:00
Juergen Hoeller 568e963466 Annotation post-processors clear old InjectionMetadata registrations on refresh
Issue: SPR-12526
(cherry picked from commit e118086)
2014-12-29 20:02:06 +01:00
Stephane Nicoll c50886ce03 Fix scope inheritance documentation
Issue: SPR-12570
2014-12-29 11:02:55 +01:00
Juergen Hoeller 2b0ada95ce AbstractApplicationEventMulticaster populates ListenerRetriever cache in fully synchronized fashion
Issue: SPR-12545
2014-12-22 15:46:58 +01:00
Juergen Hoeller 4efe6a8a5c AbstractFallbackTransactionAttributeSource's DefaultCacheKey takes targetClass into account (again)
Issue: SPR-12536
2014-12-22 14:01:19 +01:00
Juergen Hoeller ec3967a6c7 Consistent bridge method handling in annotation post-processors
Issue: SPR-12495
Issue: SPR-12187
(cherry picked from commit d97add0)
2014-12-22 13:44:01 +01:00
Juergen Hoeller 4c5e17ec3e Consistent resolution of Class methods and static methods
Issue: SPR-12502
(cherry picked from commit 9ef0bdc)
2014-12-07 23:56:06 +01:00
Juergen Hoeller 9413204838 Polishing
(cherry picked from commit 50c578c)
2014-11-28 22:06:45 +01:00
Juergen Hoeller 925c46e445 Polishing
Issue: SPR-12476
(cherry picked from commit c89d8ec)
2014-11-27 21:26:25 +01:00
Juergen Hoeller a6a837bc3b Revised SqlRowSet javadoc
Issue: SPR-12476
2014-11-27 17:59:49 +01:00
Juergen Hoeller 0e3b26da27 ExtendedBeanInfo ignores invalid bean properties (analogous to the JavaBeans Introspector)
Issue: SPR-12434
(cherry picked from commit b45f1aa)
2014-11-27 01:56:47 +01:00
Juergen Hoeller 98cbae7fdc Polishing
Issue: SPR-12462
(cherry picked from commit 5be50c8)
2014-11-24 19:11:22 +01:00
Brian Clozel 379d2e6da0 Fix location checks for servlet 3 resources
SPR-12354 applied new checks to make sure that served static resources
are under authorized locations.

Prior to this change, serving static resources from Servlet 3 locations
such as "/webjars/" would not work since those locations can be within
one of the JARs on path. In that case, the checkLocation method would
return false and disallow serving that static resource.

This change fixes this issue by making sure to call the
`ServletContextResource.getPath()` method for servlet context resources.

Note that there's a known workaround for this issue, which is using a
classpath scheme as location, such as:
"classpath:/META-INF/resources/webjars/" instead of "/webjars".

Issue: SPR-12432
(cherry picked from commit 1214624)
2014-11-24 19:11:15 +01:00
Brian Clozel c75e370eaf Use https for maven repositories
(cherry picked from commit 493e846)
2014-11-24 19:07:57 +01:00
Juergen Hoeller 4b4bc2dae0 Revised fix for SPR-12334, now finding duplicates at the collectImports level
Issue: SPR-12442
2014-11-22 23:59:12 +01:00
Juergen Hoeller feb6552d2c Avoid early initialization of Derby driver (for "derby.stream.error.method" system property)
Issue: SPR-12437
2014-11-22 23:21:31 +01:00
Juergen Hoeller 7f1e5a49a4 Polishing
(cherry picked from commit 2675ce7)
2014-11-22 23:19:48 +01:00
Juergen Hoeller f6e1856276 Rearranged WebAsyncTask constructor interdependencies and assertions
Issue: SPR-12457
(cherry picked from commit aadb93f)
2014-11-22 23:19:41 +01:00
Juergen Hoeller d02d9cea4e MethodParameter generally uses volatile variables where applicable now (as well as a local copy of the parameterNameDiscoverer field)
Issue: SPR-12453
(cherry picked from commit 7fcadaa)
2014-11-22 23:19:35 +01:00
Spring Buildmaster cf5077861a Next Development Version 2014-11-11 02:26:26 -08:00
381 changed files with 7526 additions and 6290 deletions
+1
View File
@@ -30,6 +30,7 @@ spring-*/src/main/java/META-INF/MANIFEST.MF
*.iml
*.ipr
*.iws
.idea
out
test-output
atlassian-ide-plugin.xml
-8
View File
@@ -19,14 +19,6 @@ in our [JIRA issue tracker][] to see if you can find something similar. If not,
please create a new issue before submitting a pull request unless the change is
truly trivial, e.g. typo fixes, removing compiler warnings, etc.
## Discuss non-trivial contribution ideas with committers
If you're considering anything more than correcting a typo or fixing a minor
bug, please discuss it on the [spring-framework-contrib][] mailing list before
submitting a pull request. We're happy to provide guidance, but please spend an
hour or two researching the subject on your own including searching the mailing
list for prior discussions.
## Sign the Contributor License Agreement
If you have not previously done so, please fill out and submit the
+26 -26
View File
@@ -1,10 +1,10 @@
buildscript {
repositories {
maven { url "http://repo.springsource.org/plugins-release" }
maven { url "https://repo.spring.io/plugins-release" }
}
dependencies {
classpath("org.springframework.build.gradle:propdeps-plugin:0.0.7")
classpath("org.springframework.build.gradle:docbook-reference-plugin:0.2.8")
classpath("io.spring.gradle:docbook-reference-plugin:0.3.1")
}
}
@@ -74,7 +74,7 @@ configure(allprojects) { project ->
}
repositories {
maven { url "http://repo.spring.io/libs-release" }
maven { url "https://repo.spring.io/libs-release" }
}
dependencies {
@@ -182,7 +182,7 @@ project("spring-core") {
// avoids including two different copies of asm unnecessarily. If however future cglib
// versions drift from the version of asm used by Spring internally, this duplication
// will become necessary.
def asmVersion = "5.0.3"
def asmVersion = "5.0.4"
def cglibVersion = "3.1"
configurations {
@@ -359,7 +359,7 @@ project("spring-tx") {
compile(project(":spring-beans"))
compile(project(":spring-core"))
optional(project(":spring-aop"))
optional(project(":spring-context")) // for JCA, @EnableTransactionManagement
optional(project(":spring-context")) // for JCA, @EnableTransactionManagement
optional("aopalliance:aopalliance:1.0")
optional("org.apache.geronimo.specs:geronimo-jta_1.1_spec:1.1")
optional("javax.resource:connector-api:1.5")
@@ -434,7 +434,7 @@ project("spring-jdbc") {
compile(project(":spring-beans"))
compile(project(":spring-core"))
compile(project(":spring-tx"))
optional(project(":spring-context")) // for JndiDataSourceLookup
optional(project(":spring-context")) // for JndiDataSourceLookup
optional("org.apache.geronimo.specs:geronimo-jta_1.1_spec:1.1")
optional("c3p0:c3p0:0.9.1.2")
optional("hsqldb:hsqldb:${hsqldbVersion}")
@@ -452,8 +452,8 @@ project("spring-context-support") {
compile(project(":spring-beans"))
compile(project(":spring-context"))
provided("javax.activation:activation:1.1")
optional(project(":spring-jdbc")) // for Quartz support
optional(project(":spring-tx")) // for Quartz support
optional(project(":spring-jdbc")) // for Quartz support
optional(project(":spring-tx")) // for Quartz support
optional("javax.mail:mail:1.4.7")
optional("javax.cache:cache-api:0.5")
optional("net.sf.ehcache:ehcache-core:2.0.1")
@@ -464,8 +464,8 @@ project("spring-context-support") {
optional("com.lowagie:itext:2.1.7")
optional("net.sf.jasperreports:jasperreports:3.7.6")
testCompile("org.apache.poi:poi:3.6")
testCompile("commons-beanutils:commons-beanutils:1.8.0") // for Velocity/JasperReports
testCompile("commons-digester:commons-digester:1.8.1") // for Velocity/JasperReports
testCompile("commons-beanutils:commons-beanutils:1.8.0") // for Velocity/JasperReports
testCompile("commons-digester:commons-digester:1.8.1") // for Velocity/JasperReports
testCompile("hsqldb:hsqldb:${hsqldbVersion}")
testCompile("org.slf4j:slf4j-api:${slf4jVersion}")
}
@@ -478,13 +478,13 @@ project("spring-web") {
description = "Spring Web"
dependencies {
compile(project(":spring-aop")) // for JaxWsPortProxyFactoryBean
compile(project(":spring-beans")) // for MultiPartFilter
compile(project(":spring-aop")) // for JaxWsPortProxyFactoryBean
compile(project(":spring-beans")) // for MultipartFilter
compile(project(":spring-context"))
compile(project(":spring-core"))
provided("javax.servlet:javax.servlet-api:3.0.1")
provided("javax.activation:activation:1.1")
optional(project(":spring-oxm")) // for MarshallingHttpMessageConverter
optional(project(":spring-oxm")) // for MarshallingHttpMessageConverter
optional("javax.servlet.jsp:jsp-api:2.1")
optional("javax.portlet:portlet-api:2.0")
optional("javax.el:el-api:1.0")
@@ -562,8 +562,8 @@ project("spring-orm-hibernate4") {
provided(project(":spring-jdbc"))
provided(project(":spring-tx"))
optional(project(":spring-web"))
optional("org.hibernate:hibernate-core:4.2.15.Final")
optional("org.hibernate:hibernate-entitymanager:4.2.15.Final")
optional("org.hibernate:hibernate-core:4.2.21.Final")
optional("org.hibernate:hibernate-entitymanager:4.2.21.Final")
optional("javax.servlet:servlet-api:2.5")
}
}
@@ -578,8 +578,8 @@ project("spring-webmvc") {
compile(project(":spring-expression"))
compile(project(":spring-web"))
provided("javax.servlet:javax.servlet-api:3.0.1")
optional(project(":spring-context-support")) // for Velocity support
optional(project(":spring-oxm")) // for MarshallingView
optional(project(":spring-context-support")) // for Velocity support
optional(project(":spring-oxm")) // for MarshallingView
optional("javax.servlet.jsp:jsp-api:2.1")
optional("javax.servlet:jstl:1.2")
optional("net.sourceforge.jexcelapi:jxl:2.6.12")
@@ -786,13 +786,13 @@ project("spring-aspects") {
rt("org.aspectj:aspectjrt:${aspectjVersion}")
compile("org.aspectj:aspectjweaver:${aspectjVersion}")
provided("javax.persistence:persistence-api:1.0")
optional(project(":spring-aop")) // for @Async support
optional(project(":spring-beans")) // for @Configurable support
optional(project(":spring-context")) // for @Enable* support
optional(project(":spring-context-support")) // for JavaMail support
optional(project(":spring-orm")) // for JPA exception translation support
optional(project(":spring-tx")) // for JPA, @Transactional support
testCompile(project(":spring-core")) // for CodeStyleAspect
optional(project(":spring-aop")) // for @Async support
optional(project(":spring-beans")) // for @Configurable support
optional(project(":spring-context")) // for @Enable* support
optional(project(":spring-context-support")) // for JavaMail support
optional(project(":spring-orm")) // for JPA exception translation support
optional(project(":spring-tx")) // for JPA, @Transactional support
testCompile(project(":spring-core")) // for CodeStyleAspect
testCompile(project(":spring-test"))
testCompile("javax.mail:mail:1.4.7")
}
@@ -879,7 +879,7 @@ configure(rootProject) {
testCompile("javax.inject:javax.inject:1")
testCompile("javax.resource:connector-api:1.5")
testCompile("org.aspectj:aspectjweaver:${aspectjVersion}")
testCompile("org.hibernate:hibernate-core:4.2.15.Final")
testCompile("org.hibernate:hibernate-core:4.2.21.Final")
testCompile("hsqldb:hsqldb:${hsqldbVersion}")
}
@@ -1050,7 +1050,7 @@ configure(rootProject) {
task wrapper(type: Wrapper) {
description = "Generates gradlew[.bat] scripts"
gradleVersion = "1.12"
gradleVersion = "2.5"
doLast() {
def gradleOpts = "-XX:MaxPermSize=1024m -Xmx1024m"
@@ -68,8 +68,8 @@ class MergePlugin implements Plugin<Project> {
Configuration runtimeMerge = project.configurations.create("runtimeMerge")
// Ensure the IDE can reference merged projects
project.eclipse.classpath.plusConfigurations += [runtimeMerge]
project.idea.module.scopes.PROVIDED.plus += runtimeMerge
project.eclipse.classpath.plusConfigurations += [ runtimeMerge ]
project.idea.module.scopes.PROVIDED.plus += [ runtimeMerge ]
// Hook to perform the actual merge logic
project.afterEvaluate{
@@ -132,8 +132,9 @@ class MergePlugin implements Plugin<Project> {
intoConfiguration.dependencies.add(it)
}
}
def index = project.parent.childProjects.findIndexOf {p -> p.getValue() == project}
project.merge.into.install.repositories.mavenInstaller.pom.scopeMappings.addMapping(
mapping.priority + 100, intoConfiguration, mapping.scope)
mapping.priority + 100 + index, intoConfiguration, mapping.scope)
}
}
}
+1 -1
View File
@@ -1 +1 @@
version=3.2.12.RELEASE
version=3.2.18.RELEASE
+11
View File
@@ -41,6 +41,17 @@ eclipse.classpath.file.whenMerged { classpath ->
}
}
// Ensure project dependencies come after 3rd-party libs (SPR-11836)
// https://jira.spring.io/browse/SPR-11836
eclipse.classpath.file.whenMerged { classpath ->
classpath.entries.findAll { it instanceof ProjectDependency }.each {
// delete from original position
classpath.entries.remove(it)
// append to end of classpath
classpath.entries.add(it)
}
}
// Allow projects to be used as WPT modules
eclipse.project.natures "org.eclipse.wst.common.project.facet.core.nature"
+1 -1
View File
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-1.12-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-bin.zip
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ package org.springframework.aop.aspectj;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@@ -200,8 +201,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
pointcutParameters[i] = parser.createPointcutParameter(
this.pointcutParameterNames[i], this.pointcutParameterTypes[i]);
}
return parser.parsePointcutExpression(
replaceBooleanOperators(getExpression()),
return parser.parsePointcutExpression(replaceBooleanOperators(getExpression()),
this.pointcutDeclarationScope, pointcutParameters);
}
@@ -319,29 +319,41 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
catch (IllegalStateException ex) {
// No current invocation...
// TODO: Should we really proceed here?
logger.debug("Couldn't access current invocation - matching with limited context: " + ex);
}
JoinPointMatch joinPointMatch = shadowMatch.matchesJoinPoint(thisObject, targetObject, args);
/*
* Do a final check to see if any this(TYPE) kind of residue match. For
* this purpose, we use the original method's (proxy method's) shadow to
* ensure that 'this' is correctly checked against. Without this check,
* we get incorrect match on this(TYPE) where TYPE matches the target
* type but not 'this' (as would be the case of JDK dynamic proxies).
* <p>See SPR-2979 for the original bug.
*/
if (pmi != null) { // there is a current invocation
RuntimeTestWalker originalMethodResidueTest = getRuntimeTestWalker(originalShadowMatch);
if (!originalMethodResidueTest.testThisInstanceOfResidue(thisObject.getClass())) {
return false;
}
if (joinPointMatch.matches()) {
bindParameters(pmi, joinPointMatch);
if (logger.isDebugEnabled()) {
logger.debug("Could not access current invocation - matching with limited context: " + ex);
}
}
return joinPointMatch.matches();
try {
JoinPointMatch joinPointMatch = shadowMatch.matchesJoinPoint(thisObject, targetObject, args);
/*
* Do a final check to see if any this(TYPE) kind of residue match. For
* this purpose, we use the original method's (proxy method's) shadow to
* ensure that 'this' is correctly checked against. Without this check,
* we get incorrect match on this(TYPE) where TYPE matches the target
* type but not 'this' (as would be the case of JDK dynamic proxies).
* <p>See SPR-2979 for the original bug.
*/
if (pmi != null) { // there is a current invocation
RuntimeTestWalker originalMethodResidueTest = getRuntimeTestWalker(originalShadowMatch);
if (!originalMethodResidueTest.testThisInstanceOfResidue(thisObject.getClass())) {
return false;
}
if (joinPointMatch.matches()) {
bindParameters(pmi, joinPointMatch);
}
}
return joinPointMatch.matches();
}
catch (Throwable ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to evaluate join point for arguments " + Arrays.asList(args) +
" - falling back to non-match", ex);
}
return false;
}
}
protected String getCurrentProxiedBeanName() {
@@ -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.
@@ -18,9 +18,11 @@ package org.springframework.aop.aspectj.annotation;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanFactory;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
@@ -66,7 +68,9 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
* @param name the name of the bean
* @param type the type that should be introspected by AspectJ
*/
public BeanFactoryAspectInstanceFactory(BeanFactory beanFactory, String name, Class type) {
public BeanFactoryAspectInstanceFactory(BeanFactory beanFactory, String name, Class<?> type) {
Assert.notNull(beanFactory, "BeanFactory must not be null");
Assert.notNull(name, "Bean name must not be null");
this.beanFactory = beanFactory;
this.name = name;
this.aspectMetadata = new AspectMetadata(type, name);
@@ -78,18 +82,31 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
}
public ClassLoader getAspectClassLoader() {
if (this.beanFactory instanceof ConfigurableBeanFactory) {
return ((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader();
}
else {
return ClassUtils.getDefaultClassLoader();
}
return (this.beanFactory instanceof ConfigurableBeanFactory ?
((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader() :
ClassUtils.getDefaultClassLoader());
}
public AspectMetadata getAspectMetadata() {
return this.aspectMetadata;
}
public Object getAspectCreationMutex() {
if (this.beanFactory != null) {
if (this.beanFactory.isSingleton(this.name)) {
// Rely on singleton semantics provided by the factory -> no local lock.
return null;
}
else if (this.beanFactory instanceof AbstractBeanFactory) {
// 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 ((AbstractBeanFactory) this.beanFactory).getSingletonMutex();
}
}
return this;
}
/**
* Determine the order for this factory's target aspect, either
* an instance-specific order expressed through implementing the
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 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.
@@ -42,11 +42,20 @@ public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwar
}
public synchronized Object getAspectInstance() {
public Object getAspectInstance() {
if (this.materialized == null) {
synchronized (this) {
if (this.materialized == null) {
this.materialized = this.maaif.getAspectInstance();
Object mutex = this;
if (this.maaif instanceof BeanFactoryAspectInstanceFactory) {
mutex = ((BeanFactoryAspectInstanceFactory) this.maaif).getAspectCreationMutex();
}
if (mutex == null) {
this.materialized = this.maaif.getAspectInstance();
}
else {
synchronized (mutex) {
if (this.materialized == null) {
this.materialized = this.maaif.getAspectInstance();
}
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -93,7 +93,7 @@ final class CglibAopProxy implements AopProxy, Serializable {
/** Logger available to subclasses; static to optimize serialization */
protected final static Log logger = LogFactory.getLog(CglibAopProxy.class);
protected static final Log logger = LogFactory.getLog(CglibAopProxy.class);
/** Keeps track of the Classes that we have validated for final methods */
private static final Map<Class<?>, Boolean> validatedClasses = new WeakHashMap<Class<?>, Boolean>();
@@ -294,13 +294,13 @@ final class CglibAopProxy implements AopProxy, Serializable {
Callback targetDispatcher = isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp();
Callback[] mainCallbacks = new Callback[]{
aopInterceptor, // for normal advice
targetInterceptor, // invoke target without considering advice, if optimized
new SerializableNoOp(), // no override for methods mapped to this
targetDispatcher, this.advisedDispatcher,
new EqualsInterceptor(this.advised),
new HashCodeInterceptor(this.advised)
Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // for normal advice
targetInterceptor, // invoke target without considering advice, if optimized
new SerializableNoOp(), // no override for methods mapped to this
targetDispatcher, this.advisedDispatcher,
new EqualsInterceptor(this.advised),
new HashCodeInterceptor(this.advised)
};
Callback[] callbacks;
@@ -678,10 +678,11 @@ final class CglibAopProxy implements AopProxy, Serializable {
private final MethodProxy methodProxy;
private boolean protectedMethod;
private final boolean protectedMethod;
public CglibMethodInvocation(Object proxy, Object target, Method method, Object[] arguments,
Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
this.methodProxy = methodProxy;
this.protectedMethod = Modifier.isProtected(method.getModifiers());
@@ -800,8 +801,7 @@ final class CglibAopProxy implements AopProxy, Serializable {
if (logger.isDebugEnabled()) {
logger.debug("Method has advice and optimisations are enabled: " + method);
}
// We know that we are optimising so we can use the
// FixedStaticChainInterceptors.
// We know that we are optimising so we can use the FixedStaticChainInterceptors.
int index = this.fixedInterceptorMap.get(key);
return (index + this.fixedInterceptorOffset);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,7 +31,7 @@ import org.springframework.util.StringUtils;
/**
* Base class for asynchronous method execution aspects, such as
* {@link org.springframework.scheduling.annotation.AnnotationAsyncExecutionInterceptor}
* {@code org.springframework.scheduling.annotation.AnnotationAsyncExecutionInterceptor}
* or {@code org.springframework.scheduling.aspectj.AnnotationAsyncExecutionAspect}.
*
* <p>Provides support for <i>executor qualification</i> on a method-by-method basis.
@@ -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.
@@ -23,6 +23,7 @@ import org.aopalliance.aop.Advice;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.support.AbstractBeanFactory;
import org.springframework.util.Assert;
/**
@@ -45,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();
@@ -71,8 +72,23 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
resetAdviceMonitor();
}
private void resetAdviceMonitor() {
if (this.beanFactory instanceof AbstractBeanFactory) {
this.adviceMonitor = ((AbstractBeanFactory) this.beanFactory).getSingletonMutex();
}
else {
this.adviceMonitor = new Object();
}
}
/**
* Specify a particular instance of the target advice directly,
* avoiding lazy resolution in {@link #getAdvice()}.
* @since 3.1
*/
public void setAdvice(Advice advice) {
synchronized (this.adviceMonitor) {
this.advice = advice;
@@ -80,18 +96,42 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
}
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;
}
}
@Override
public String toString() {
return getClass().getName() + ": advice bean '" + getAdviceBeanName() + "'";
StringBuilder sb = new StringBuilder(getClass().getName());
sb.append(": advice ");
if (this.adviceBeanName != null) {
sb.append("bean '").append(this.adviceBeanName).append("'");
}
else {
sb.append(this.advice);
}
return sb.toString();
}
@@ -104,7 +144,7 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
ois.defaultReadObject();
// Initialize transient fields.
this.adviceMonitor = new Object();
resetAdviceMonitor();
}
}
@@ -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,23 +28,23 @@ 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 boolean equals(Object other) {
if (!(other instanceof NopInterceptor)) {
return false;
@@ -56,4 +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.
@@ -29,17 +29,9 @@ import org.springframework.util.ObjectUtils;
public class SerializablePerson implements Person, Serializable {
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() {
@@ -51,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) {
@@ -59,6 +61,8 @@ public class SerializablePerson implements Person, Serializable {
return o;
}
@Override
public boolean equals(Object other) {
if (!(other instanceof SerializablePerson)) {
return false;
@@ -67,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,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,9 +28,9 @@ import org.springframework.context.annotation.Role;
* annotated with @{@link org.springframework.beans.factory.annotation.Configurable
* Configurable}.
*
* <p>This configuration class is automatically imported when using the @{@link
* EnableSpringConfigured} annotation. See {@code @EnableSpringConfigured} Javadoc for
* complete usage details.
* <p>This configuration class is automatically imported when using the
* @{@link EnableSpringConfigured} annotation. See {@code @EnableSpringConfigured}'s
* javadoc for complete usage details.
*
* @author Chris Beams
* @since 3.1
@@ -42,9 +42,10 @@ public class SpringConfiguredConfiguration {
public static final String BEAN_CONFIGURER_ASPECT_BEAN_NAME =
"org.springframework.context.config.internalBeanConfigurerAspect";
@Bean(name=BEAN_CONFIGURER_ASPECT_BEAN_NAME)
@Bean(name = BEAN_CONFIGURER_ASPECT_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public AnnotationBeanConfigurerAspect beanConfigurerAspect() {
return AnnotationBeanConfigurerAspect.aspectOf();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -105,7 +105,7 @@ public abstract class AbstractPropertyAccessor extends TypeConverterSupport impl
// Redefined with public visibility.
@Override
public Class getPropertyType(String propertyPath) {
public Class<?> getPropertyType(String propertyPath) {
return null;
}
@@ -127,7 +127,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
*/
public abstract void setPropertyValue(String propertyName, Object value) throws BeansException;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -379,13 +379,28 @@ public abstract class BeanUtils {
* Find a JavaBeans {@code PropertyDescriptor} for the given method,
* with the method either being the read method or the write method for
* that bean property.
* @param method the method to find a corresponding PropertyDescriptor for
* @param method the method to find a corresponding PropertyDescriptor for,
* introspecting its declaring class
* @return the corresponding PropertyDescriptor, or {@code null} if none
* @throws BeansException if PropertyDescriptor lookup fails
*/
public static PropertyDescriptor findPropertyForMethod(Method method) throws BeansException {
return findPropertyForMethod(method, method.getDeclaringClass());
}
/**
* Find a JavaBeans {@code PropertyDescriptor} for the given method,
* with the method either being the read method or the write method for
* that bean property.
* @param method the method to find a corresponding PropertyDescriptor for
* @param clazz the (most specific) class to introspect for descriptors
* @return the corresponding PropertyDescriptor, or {@code null} if none
* @throws BeansException if PropertyDescriptor lookup fails
* @since 3.2.13
*/
public static PropertyDescriptor findPropertyForMethod(Method method, Class<?> clazz) throws BeansException {
Assert.notNull(method, "Method must not be null");
PropertyDescriptor[] pds = getPropertyDescriptors(method.getDeclaringClass());
PropertyDescriptor[] pds = getPropertyDescriptors(clazz);
for (PropertyDescriptor pd : pds) {
if (method.equals(pd.getReadMethod()) || method.equals(pd.getWriteMethod())) {
return pd;
@@ -591,11 +606,11 @@ public abstract class BeanUtils {
actualEditable = editable;
}
PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
List<String> ignoreList = (ignoreProperties != null) ? Arrays.asList(ignoreProperties) : null;
List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);
for (PropertyDescriptor targetPd : targetPds) {
Method writeMethod = targetPd.getWriteMethod();
if (writeMethod != null && (ignoreProperties == null || (!ignoreList.contains(targetPd.getName())))) {
if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {
PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
if (sourcePd != null) {
Method readMethod = sourcePd.getReadMethod();
@@ -1025,7 +1025,7 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
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 [" + pv.getValue() + "]");
"' is neither an array nor a List nor a Map; returned value was [" + propValue + "]");
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,6 +35,9 @@ import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import static org.springframework.beans.PropertyDescriptorUtils.*;
/**
@@ -73,6 +76,8 @@ import static org.springframework.beans.PropertyDescriptorUtils.*;
*/
class ExtendedBeanInfo implements BeanInfo {
private static final Log logger = LogFactory.getLog(ExtendedBeanInfo.class);
private final BeanInfo delegate;
private final Set<PropertyDescriptor> propertyDescriptors =
@@ -94,14 +99,30 @@ class ExtendedBeanInfo implements BeanInfo {
public ExtendedBeanInfo(BeanInfo delegate) throws IntrospectionException {
this.delegate = delegate;
for (PropertyDescriptor pd : delegate.getPropertyDescriptors()) {
this.propertyDescriptors.add(pd instanceof IndexedPropertyDescriptor ?
new SimpleIndexedPropertyDescriptor((IndexedPropertyDescriptor) pd) :
new SimplePropertyDescriptor(pd));
try {
this.propertyDescriptors.add(pd instanceof IndexedPropertyDescriptor ?
new SimpleIndexedPropertyDescriptor((IndexedPropertyDescriptor) pd) :
new SimplePropertyDescriptor(pd));
}
catch (IntrospectionException ex) {
// Probably simply a method that wasn't meant to follow the JavaBeans pattern...
if (logger.isDebugEnabled()) {
logger.debug("Ignoring invalid bean property '" + pd.getName() + "': " + ex.getMessage());
}
}
}
MethodDescriptor[] methodDescriptors = delegate.getMethodDescriptors();
if (methodDescriptors != null) {
for (Method method : findCandidateWriteMethods(methodDescriptors)) {
handleCandidateWriteMethod(method);
try {
handleCandidateWriteMethod(method);
}
catch (IntrospectionException ex) {
// We're only trying to find candidates, can easily ignore extra ones here...
if (logger.isDebugEnabled()) {
logger.debug("Ignoring candidate write method [" + method + "]: " + ex.getMessage());
}
}
}
}
}
@@ -130,15 +151,15 @@ class ExtendedBeanInfo implements BeanInfo {
String methodName = method.getName();
Class<?>[] parameterTypes = method.getParameterTypes();
int nParams = parameterTypes.length;
return methodName.length() > 3 && methodName.startsWith("set") && Modifier.isPublic(method.getModifiers()) &&
return (methodName.length() > 3 && methodName.startsWith("set") && Modifier.isPublic(method.getModifiers()) &&
(!void.class.isAssignableFrom(method.getReturnType()) || Modifier.isStatic(method.getModifiers())) &&
(nParams == 1 || (nParams == 2 && parameterTypes[0].equals(int.class)));
(nParams == 1 || (nParams == 2 && parameterTypes[0].equals(int.class))));
}
private void handleCandidateWriteMethod(Method method) throws IntrospectionException {
int nParams = method.getParameterTypes().length;
String propertyName = propertyNameFor(method);
Class<?> propertyType = method.getParameterTypes()[nParams-1];
Class<?> propertyType = method.getParameterTypes()[nParams - 1];
PropertyDescriptor existingPd = findExistingPropertyDescriptor(propertyName, propertyType);
if (nParams == 1) {
if (existingPd == null) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -88,7 +88,8 @@ class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor {
Set<Method> ambiguousCandidates = new HashSet<Method>();
for (Method method : beanClass.getMethods()) {
if (method.getName().equals(writeMethodToUse.getName()) &&
!method.equals(writeMethodToUse) && !method.isBridge()) {
!method.equals(writeMethodToUse) && !method.isBridge() &&
method.getParameterTypes().length == writeMethodToUse.getParameterTypes().length) {
ambiguousCandidates.add(method);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -86,7 +86,7 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
// There is no replacement of existing property values.
if (original != null) {
this.propertyValueList = new ArrayList<PropertyValue>(original.size());
for (Map.Entry entry : original.entrySet()) {
for (Map.Entry<?, ?> entry : original.entrySet()) {
this.propertyValueList.add(new PropertyValue(entry.getKey().toString(), entry.getValue()));
}
}
@@ -303,6 +303,16 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
this.processedProperties.add(propertyName);
}
/**
* Clear the "processed" registration of the given property, if any.
* @since 3.2.13
*/
public void clearProcessedProperty(String propertyName) {
if (this.processedProperties != null) {
this.processedProperties.remove(propertyName);
}
}
/**
* Mark this holder as containing converted values only
* (i.e. no runtime resolution needed anymore).
@@ -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.
@@ -86,7 +86,7 @@ public interface PropertyAccessor {
* @throws PropertyAccessException if the property was valid but the
* accessor method failed
*/
Class getPropertyType(String propertyName) throws BeansException;
Class<?> getPropertyType(String propertyName) throws BeansException;
/**
* Return a type descriptor for the specified property:
@@ -120,7 +120,7 @@ public interface PropertyAccessor {
* @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
*/
void setPropertyValue(String propertyName, Object value) throws BeansException;
@@ -130,7 +130,7 @@ public interface PropertyAccessor {
* @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
*/
void setPropertyValue(PropertyValue pv) throws BeansException;
@@ -144,7 +144,7 @@ public interface PropertyAccessor {
* @throws InvalidPropertyException if there is no such property or
* if the property isn't writable
* @throws PropertyBatchUpdateException if one or more PropertyAccessExceptions
* occured for specific properties during the batch update. This exception bundles
* occurred for specific properties during the batch update. This exception bundles
* all individual PropertyAccessExceptions. All other properties will have been
* successfully updated.
*/
@@ -164,7 +164,7 @@ public interface PropertyAccessor {
* @throws InvalidPropertyException if there is no such property or
* if the property isn't writable
* @throws PropertyBatchUpdateException if one or more PropertyAccessExceptions
* occured for specific properties during the batch update. This exception bundles
* occurred for specific properties during the batch update. This exception bundles
* all individual PropertyAccessExceptions. All other properties will have been
* successfully updated.
* @see #setPropertyValues(PropertyValues, boolean, boolean)
@@ -185,7 +185,7 @@ public interface PropertyAccessor {
* @throws InvalidPropertyException if there is no such property or
* if the property isn't writable
* @throws PropertyBatchUpdateException if one or more PropertyAccessExceptions
* occured for specific properties during the batch update. This exception bundles
* occurred for specific properties during the batch update. This exception bundles
* all individual PropertyAccessExceptions. All other properties will have been
* successfully updated.
* @see #setPropertyValues(PropertyValues, boolean, boolean)
@@ -208,7 +208,7 @@ public interface PropertyAccessor {
* @throws InvalidPropertyException if there is no such property or
* if the property isn't writable
* @throws PropertyBatchUpdateException if one or more PropertyAccessExceptions
* occured for specific properties during the batch update. This exception bundles
* occurred for specific properties during the batch update. This exception bundles
* all individual PropertyAccessExceptions. All other properties will have been
* successfully updated.
*/
@@ -130,7 +130,7 @@ public class PropertyBatchUpdateException extends BeansException {
}
@Override
public boolean contains(Class exType) {
public boolean contains(Class<?> exType) {
if (exType == null) {
return false;
}
@@ -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.
@@ -46,8 +46,6 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri
private final Object value;
private Object source;
private boolean optional = false;
private boolean converted = false;
@@ -82,13 +80,13 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri
Assert.notNull(original, "Original must not be null");
this.name = original.getName();
this.value = original.getValue();
this.source = original.getSource();
this.optional = original.isOptional();
this.converted = original.converted;
this.convertedValue = original.convertedValue;
this.conversionNecessary = original.conversionNecessary;
this.resolvedTokens = original.resolvedTokens;
this.resolvedDescriptor = original.resolvedDescriptor;
setSource(original.getSource());
copyAttributesFrom(original);
}
@@ -102,11 +100,11 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri
Assert.notNull(original, "Original must not be null");
this.name = original.getName();
this.value = newValue;
this.source = original;
this.optional = original.isOptional();
this.conversionNecessary = original.conversionNecessary;
this.resolvedTokens = original.resolvedTokens;
this.resolvedDescriptor = original.resolvedDescriptor;
setSource(original);
copyAttributesFrom(original);
}
@@ -135,16 +133,28 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri
*/
public PropertyValue getOriginalPropertyValue() {
PropertyValue original = this;
while (original.source instanceof PropertyValue && original.source != original) {
original = (PropertyValue) original.source;
Object source = getSource();
while (source instanceof PropertyValue && source != original) {
original = (PropertyValue) source;
source = original.getSource();
}
return original;
}
/**
* Set whether this is an optional value, that is, to be ignored
* when no corresponding property exists on the target class.
* @since 3.0
*/
public void setOptional(boolean optional) {
this.optional = optional;
}
/**
* Return whether this is an optional value, that is, to be ignored
* when no corresponding property exists on the target class.
* @since 3.0
*/
public boolean isOptional() {
return this.optional;
}
@@ -186,7 +196,7 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri
PropertyValue otherPv = (PropertyValue) other;
return (this.name.equals(otherPv.name) &&
ObjectUtils.nullSafeEquals(this.value, otherPv.value) &&
ObjectUtils.nullSafeEquals(this.source, otherPv.source));
ObjectUtils.nullSafeEquals(getSource(), otherPv.getSource()));
}
@Override
@@ -123,7 +123,7 @@ public class BeanCreationException extends FatalBeanException {
/**
* Add a related cause to this bean creation exception,
* not being a direct cause of the failure but having occured
* not being a direct cause of the failure but having occurred
* earlier in the creation of the same bean instance.
* @param ex the related cause to add
*/
@@ -185,7 +185,7 @@ public class BeanCreationException extends FatalBeanException {
}
@Override
public boolean contains(Class exClass) {
public boolean contains(Class<?> exClass) {
if (super.contains(exClass)) {
return true;
}
@@ -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.
@@ -66,24 +66,27 @@ import org.springframework.beans.BeansException;
* 1. BeanNameAware's {@code setBeanName}<br>
* 2. BeanClassLoaderAware's {@code setBeanClassLoader}<br>
* 3. BeanFactoryAware's {@code setBeanFactory}<br>
* 4. ResourceLoaderAware's {@code setResourceLoader}
* 4. EnvironmentAware's {@code setEnvironment}
* 5. EmbeddedValueResolverAware's {@code setEmbeddedValueResolver}
* 6. ResourceLoaderAware's {@code setResourceLoader}
* (only applicable when running in an application context)<br>
* 5. ApplicationEventPublisherAware's {@code setApplicationEventPublisher}
* 7. ApplicationEventPublisherAware's {@code setApplicationEventPublisher}
* (only applicable when running in an application context)<br>
* 6. MessageSourceAware's {@code setMessageSource}
* 8. MessageSourceAware's {@code setMessageSource}
* (only applicable when running in an application context)<br>
* 7. ApplicationContextAware's {@code setApplicationContext}
* 9. ApplicationContextAware's {@code setApplicationContext}
* (only applicable when running in an application context)<br>
* 8. ServletContextAware's {@code setServletContext}
* 10. ServletContextAware's {@code setServletContext}
* (only applicable when running in a web application context)<br>
* 9. {@code postProcessBeforeInitialization} methods of BeanPostProcessors<br>
* 10. InitializingBean's {@code afterPropertiesSet}<br>
* 11. a custom init-method definition<br>
* 12. {@code postProcessAfterInitialization} methods of BeanPostProcessors
* 11. {@code postProcessBeforeInitialization} methods of BeanPostProcessors<br>
* 12. InitializingBean's {@code afterPropertiesSet}<br>
* 13. a custom init-method definition<br>
* 14. {@code postProcessAfterInitialization} methods of BeanPostProcessors
*
* <p>On shutdown of a bean factory, the following lifecycle methods apply:<br>
* 1. DisposableBean's {@code destroy}<br>
* 2. a custom destroy-method definition
* 1. {@code postProcessBeforeDestruction} methods of DestructionAwareBeanPostProcessors
* 2. DisposableBean's {@code destroy}<br>
* 3. a custom destroy-method definition
*
* @author Rod Johnson
* @author Juergen Hoeller
@@ -114,6 +117,7 @@ public interface BeanFactory {
*/
String FACTORY_BEAN_PREFIX = "&";
/**
* Return an instance, which may be shared or independent, of the specified bean.
* <p>This method allows a Spring BeanFactory to be used as a replacement for the
@@ -151,15 +155,16 @@ public interface BeanFactory {
/**
* Return the bean instance that uniquely matches the given object type, if any.
* @param requiredType type the bean must match; can be an interface or superclass.
* {@code null} is disallowed.
* <p>This method goes into {@link ListableBeanFactory} by-type lookup territory
* but may also be translated into a conventional by-name lookup based on the name
* of the given type. For more extensive retrieval operations across sets of beans,
* use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}.
* @param requiredType type the bean must match; can be an interface or superclass.
* {@code null} is disallowed.
* @return an instance of the single bean matching the required type
* @throws NoSuchBeanDefinitionException if no bean of the given type was found
* @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found
* @throws BeansException if the bean could not be created
* @since 3.0
* @see ListableBeanFactory
*/
@@ -170,7 +175,7 @@ public interface BeanFactory {
* <p>Allows for specifying explicit constructor arguments / factory method arguments,
* overriding the specified default arguments (if any) in the bean definition.
* @param name the name of the bean to retrieve
* @param args arguments to use if creating a prototype using explicit arguments
* @param args arguments to use when creating a prototype using explicit arguments
* @return an instance of the bean
* @throws NoSuchBeanDefinitionException if there is no such bean definition
* @throws BeanDefinitionStoreException if arguments have been given but
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
package org.springframework.beans.factory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2006 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.beans.factory;
/**
* Counterpart of BeanNameAware. Returns the bean name of an object.
* Counterpart of {@link BeanNameAware}. Returns the bean name of an object.
*
* <p>This interface can be introduced to avoid a brittle dependence
* on bean name in objects used with Spring IoC and Spring AOP.
* <p>This interface can be introduced to avoid a brittle dependence on
* bean name in objects used with Spring IoC and Spring AOP.
*
* @author Rod Johnson
* @since 2.0
@@ -29,7 +29,7 @@ package org.springframework.beans.factory;
public interface NamedBean {
/**
* Return the name of this bean in a Spring bean factory.
* Return the name of this bean in a Spring bean factory, if known.
*/
String getBeanName();
@@ -215,7 +215,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (beanType != null) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType);
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
}
@@ -233,8 +233,8 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
Constructor<?> requiredConstructor = null;
Constructor<?> defaultConstructor = null;
for (Constructor<?> candidate : rawCandidates) {
Annotation annotation = findAutowiredAnnotation(candidate);
if (annotation != null) {
Annotation ann = findAutowiredAnnotation(candidate);
if (ann != null) {
if (requiredConstructor != null) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructor: " + candidate +
@@ -245,7 +245,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
throw new IllegalStateException(
"Autowired annotation requires at least one argument: " + candidate);
}
boolean required = determineRequiredStatus(annotation);
boolean required = determineRequiredStatus(ann);
if (required) {
if (!candidates.isEmpty()) {
throw new BeanCreationException(beanName,
@@ -290,7 +290,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass());
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
metadata.inject(bean, beanName, pvs);
}
@@ -308,7 +308,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
*/
public void processInjection(Object bean) throws BeansException {
Class<?> clazz = bean.getClass();
InjectionMetadata metadata = findAutowiringMetadata(clazz.getName(), clazz);
InjectionMetadata metadata = findAutowiringMetadata(clazz.getName(), clazz, null);
try {
metadata.inject(bean, null, null);
}
@@ -318,15 +318,18 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
}
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz) {
// Quick check on the concurrent map first, with minimal locking.
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, PropertyValues pvs) {
// Fall back to class name as cache key, for backwards compatibility with custom callers.
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// Quick check on the concurrent map first, with minimal locking.
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
metadata = buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
@@ -342,23 +345,25 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
do {
LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<InjectionMetadata.InjectedElement>();
for (Field field : targetClass.getDeclaredFields()) {
Annotation annotation = findAutowiredAnnotation(field);
if (annotation != null) {
Annotation ann = findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static fields: " + field);
}
continue;
}
boolean required = determineRequiredStatus(annotation);
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
}
for (Method method : targetClass.getDeclaredMethods()) {
Annotation ann = null;
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
Annotation annotation = BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod) ?
findAutowiredAnnotation(bridgedMethod) : findAutowiredAnnotation(method);
if (annotation != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
ann = findAutowiredAnnotation(bridgedMethod);
}
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static methods: " + method);
@@ -370,8 +375,8 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
logger.warn("Autowired annotation should be used on methods with actual parameters: " + method);
}
}
boolean required = determineRequiredStatus(annotation);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredMethodElement(method, required, pd));
}
}
@@ -385,9 +390,9 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
private Annotation findAutowiredAnnotation(AccessibleObject ao) {
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
Annotation annotation = AnnotationUtils.getAnnotation(ao, type);
if (annotation != null) {
return annotation;
Annotation ann = AnnotationUtils.getAnnotation(ao, type);
if (ann != null) {
return ann;
}
}
return null;
@@ -412,21 +417,21 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
* <p>A 'required' dependency means that autowiring should fail when no beans
* are found. Otherwise, the autowiring process will simply bypass the field
* or method when no beans are found.
* @param annotation the Autowired annotation
* @param ann the Autowired annotation
* @return whether the annotation indicates that a dependency is required
*/
protected boolean determineRequiredStatus(Annotation annotation) {
protected boolean determineRequiredStatus(Annotation ann) {
try {
Method method = ReflectionUtils.findMethod(annotation.annotationType(), this.requiredParameterName);
Method method = ReflectionUtils.findMethod(ann.annotationType(), this.requiredParameterName);
if (method == null) {
// annotations like @Inject and @Value don't have a method (attribute) named "required"
// Annotations like @Inject and @Value don't have a method (attribute) named "required"
// -> default to required status
return true;
}
return (this.requiredParameterValue == (Boolean) ReflectionUtils.invokeMethod(method, annotation));
return (this.requiredParameterValue == (Boolean) ReflectionUtils.invokeMethod(method, ann));
}
catch (Exception ex) {
// an exception was thrown during reflective invocation of the required attribute
// An exception was thrown during reflective invocation of the required attribute
// -> default to required status
return true;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
package org.springframework.beans.factory.annotation;
import java.lang.reflect.Method;
import java.util.Map;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryUtils;
@@ -77,19 +76,19 @@ public class BeanFactoryAnnotationUtils {
* @throws NoSuchBeanDefinitionException if no matching bean of type {@code T} found
*/
private static <T> T qualifiedBeanOfType(ConfigurableListableBeanFactory bf, Class<T> beanType, String qualifier) {
Map<String, T> candidateBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(bf, beanType);
T matchingBean = null;
for (String beanName : candidateBeans.keySet()) {
String[] candidateBeans = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(bf, beanType);
String matchingBean = null;
for (String beanName : candidateBeans) {
if (isQualifierMatch(qualifier, beanName, bf)) {
if (matchingBean != null) {
throw new NoSuchBeanDefinitionException(qualifier, "No unique " + beanType.getSimpleName() +
" bean found for qualifier '" + qualifier + "'");
}
matchingBean = candidateBeans.get(beanName);
matchingBean = beanName;
}
}
if (matchingBean != null) {
return matchingBean;
return bf.getBean(matchingBean, beanType);
}
else if (bf.containsBean(qualifier)) {
// Fallback: target bean at least found by bean name - probably a manually registered singleton.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -46,7 +46,7 @@ import org.springframework.util.ReflectionUtils;
*/
public class InjectionMetadata {
private final Log logger = LogFactory.getLog(InjectionMetadata.class);
private static final Log logger = LogFactory.getLog(InjectionMetadata.class);
private final Class<?> targetClass;
@@ -60,6 +60,7 @@ public class InjectionMetadata {
this.injectedElements = elements;
}
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
Set<InjectedElement> checkedElements = new LinkedHashSet<InjectedElement>(this.injectedElements.size());
for (InjectedElement element : this.injectedElements) {
@@ -82,13 +83,26 @@ public class InjectionMetadata {
boolean debug = logger.isDebugEnabled();
for (InjectedElement element : elementsToIterate) {
if (debug) {
logger.debug("Processing injected method of bean '" + beanName + "': " + element);
logger.debug("Processing injected element of bean '" + beanName + "': " + element);
}
element.inject(target, beanName, pvs);
}
}
}
/**
* @since 3.2.13
*/
public void clear(PropertyValues pvs) {
Collection<InjectedElement> elementsToIterate =
(this.checkedElements != null ? this.checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
element.clearPropertySkipping(pvs);
}
}
}
public static boolean needsRefresh(InjectionMetadata metadata, Class<?> clazz) {
return (metadata == null || !metadata.targetClass.equals(clazz));
@@ -170,7 +184,7 @@ public class InjectionMetadata {
}
/**
* Checks whether this injector's property needs to be skipped due to
* Check whether this injector's property needs to be skipped due to
* an explicit property value having been specified. Also marks the
* affected property as processed for other processors to ignore it.
*/
@@ -201,6 +215,20 @@ public class InjectionMetadata {
}
}
/**
* @since 3.2.13
*/
protected void clearPropertySkipping(PropertyValues pvs) {
if (pvs == null) {
return;
}
synchronized (pvs) {
if (Boolean.FALSE.equals(this.skip) && this.pd != null && pvs instanceof MutablePropertyValues) {
((MutablePropertyValues) pvs).clearProcessedProperty(this.pd.getName());
}
}
}
/**
* Either this or {@link #inject} needs to be overridden.
*/
@@ -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.
@@ -153,7 +153,7 @@ public abstract class AbstractFactoryBean<T>
*/
@SuppressWarnings("unchecked")
private T getEarlySingletonInstance() throws Exception {
Class[] ifcs = getEarlySingletonInterfaces();
Class<?>[] ifcs = getEarlySingletonInterfaces();
if (ifcs == null) {
throw new FactoryBeanNotInitializedException(
getClass().getName() + " does not support circular references");
@@ -201,7 +201,7 @@ public abstract class AbstractFactoryBean<T>
* <p>Invoked on initialization of this FactoryBean in case of
* a singleton; else, on each {@link #getObject()} call.
* @return the object returned by this factory
* @throws Exception if an exception occured during object creation
* @throws Exception if an exception occurred during object creation
* @see #getObject()
*/
protected abstract T createInstance() throws Exception;
@@ -218,9 +218,9 @@ public abstract class AbstractFactoryBean<T>
* or {@code null} to indicate a FactoryBeanNotInitializedException
* @see org.springframework.beans.factory.FactoryBeanNotInitializedException
*/
protected Class[] getEarlySingletonInterfaces() {
Class type = getObjectType();
return (type != null && type.isInterface() ? new Class[] {type} : null);
protected Class<?>[] getEarlySingletonInterfaces() {
Class<?> type = getObjectType();
return (type != null && type.isInterface() ? new Class<?>[] {type} : null);
}
/**
@@ -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.
@@ -114,9 +114,9 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
* <p>Performs full initialization of the bean, including all applicable
* {@link BeanPostProcessor BeanPostProcessors}.
* <p>Note: This is intended for creating a fresh instance, populating annotated
* fields and methods as well as applying all standard bean initialiation callbacks.
* fields and methods as well as applying all standard bean initialization callbacks.
* It does <i>not</> imply traditional by-name or by-type autowiring of properties;
* use {@link #createBean(Class, int, boolean)} for that purposes.
* use {@link #createBean(Class, int, boolean)} for those purposes.
* @param beanClass the class of the bean to create
* @return the new bean instance
* @throws BeansException if instantiation or wiring failed
@@ -129,7 +129,7 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
* <p>Note: This is essentially intended for (re-)populating annotated fields and
* methods, either for new instances or for deserialized instances. It does
* <i>not</i> imply traditional by-name or by-type autowiring of properties;
* use {@link #autowireBeanProperties} for that purposes.
* use {@link #autowireBeanProperties} for those purposes.
* @param existingBean the existing bean instance
* @throws BeansException if wiring failed
*/
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 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.
@@ -91,7 +91,7 @@ public class PropertiesFactoryBean extends PropertiesLoaderSupport
* <p>Invoked on initialization of this FactoryBean in case of a
* shared singleton; else, on each {@link #getObject()} call.
* @return the object returned by this factory
* @throws IOException if an exception occured during properties loading
* @throws IOException if an exception occurred during properties loading
* @see #mergeProperties()
*/
protected Properties createProperties() throws IOException {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -219,8 +219,7 @@ public class PropertyPlaceholderConfigurer extends PlaceholderConfigurerSupport
throws BeansException {
StringValueResolver valueResolver = new PlaceholderResolvingStringValueResolver(props);
this.doProcessProperties(beanFactoryToProcess, valueResolver);
doProcessProperties(beanFactoryToProcess, valueResolver);
}
/**
@@ -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.
@@ -425,9 +425,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @see #doCreateBean
*/
@Override
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
@@ -596,7 +594,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
}
/**
* Determine the bean type for the given bean definition which is based on
* Determine the target type for the given bean definition which is based on
* a factory method. Only called if there is no singleton instance registered
* for the target bean already.
* <p>This implementation determines the type matching {@link #createBean}'s
@@ -606,7 +604,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @param mbd the merged bean definition for the bean
* @param typesToMatch the types to match in case of internal type matching purposes
* (also signals that the returned {@code Class} will never be exposed to application code)
* @return the type for the bean if determinable, or {@code null} else
* @return the type for the bean if determinable, or {@code null} otherwise
* @see #createBean
*/
protected Class<?> getTypeForFactoryMethod(String beanName, RootBeanDefinition mbd, Class[] typesToMatch) {
@@ -745,10 +743,14 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
if (objectType.value != null) {
return objectType.value;
}
else {
// No type found for shortcut FactoryBean instance:
// fall back to full creation of the FactoryBean instance.
return super.getTypeForFactoryBean(beanName, mbd);
}
}
// No type found - fall back to full creation of the FactoryBean instance.
return super.getTypeForFactoryBean(beanName, mbd);
return null;
}
/**
@@ -767,7 +769,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
if (exposedObject == null) {
return exposedObject;
return null;
}
}
}
@@ -782,8 +784,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
/**
* Obtain a "shortcut" singleton FactoryBean instance to use for a
* {@code getObjectType()} call, without full initialization
* of the FactoryBean.
* {@code getObjectType()} call, without full initialization of the FactoryBean.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @return the FactoryBean instance, or {@code null} to indicate
@@ -824,8 +825,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
/**
* Obtain a "shortcut" non-singleton FactoryBean instance to use for a
* {@code getObjectType()} call, without full initialization
* of the FactoryBean.
* {@code getObjectType()} call, without full initialization of the FactoryBean.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @return the FactoryBean instance, or {@code null} to indicate
@@ -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.
@@ -156,7 +156,7 @@ class ConstructorResolver {
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
}
AutowireUtils.sortConstructors(candidates);
@@ -613,8 +613,8 @@ class ConstructorResolver {
String beanName, RootBeanDefinition mbd, BeanWrapper bw,
ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {
TypeConverter converter = (this.beanFactory.getCustomTypeConverter() != null ?
this.beanFactory.getCustomTypeConverter() : bw);
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
TypeConverter converter = (customConverter != null ? customConverter : bw);
BeanDefinitionValueResolver valueResolver =
new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
@@ -670,8 +670,8 @@ class ConstructorResolver {
boolean autowiring) throws UnsatisfiedDependencyException {
String methodType = (methodOrCtor instanceof Constructor ? "constructor" : "factory method");
TypeConverter converter = (this.beanFactory.getCustomTypeConverter() != null ?
this.beanFactory.getCustomTypeConverter() : bw);
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
TypeConverter converter = (customConverter != null ? customConverter : bw);
ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);
Set<ConstructorArgumentValues.ValueHolder> usedValueHolders =
@@ -772,12 +772,13 @@ class ConstructorResolver {
private Object[] resolvePreparedArguments(
String beanName, RootBeanDefinition mbd, BeanWrapper bw, Member methodOrCtor, Object[] argsToResolve) {
Class<?>[] paramTypes = (methodOrCtor instanceof Method ?
((Method) methodOrCtor).getParameterTypes() : ((Constructor<?>) methodOrCtor).getParameterTypes());
TypeConverter converter = (this.beanFactory.getCustomTypeConverter() != null ?
this.beanFactory.getCustomTypeConverter() : bw);
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
TypeConverter converter = (customConverter != null ? customConverter : bw);
BeanDefinitionValueResolver valueResolver =
new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
Class<?>[] paramTypes = (methodOrCtor instanceof Method ?
((Method) methodOrCtor).getParameterTypes() : ((Constructor<?>) methodOrCtor).getParameterTypes());
Object[] resolvedArgs = new Object[argsToResolve.length];
for (int argIndex = 0; argIndex < argsToResolve.length; argIndex++) {
Object argValue = argsToResolve[argIndex];
@@ -509,10 +509,12 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
//---------------------------------------------------------------------
public void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue) {
Assert.notNull(dependencyType, "Type must not be null");
Assert.notNull(dependencyType, "Dependency type must not be null");
if (autowiredValue != null) {
Assert.isTrue((autowiredValue instanceof ObjectFactory || dependencyType.isInstance(autowiredValue)),
"Value [" + autowiredValue + "] does not implement specified type [" + dependencyType.getName() + "]");
if (!(autowiredValue instanceof ObjectFactory || dependencyType.isInstance(autowiredValue))) {
throw new IllegalArgumentException("Value [" + autowiredValue +
"] does not implement specified dependency type [" + dependencyType.getName() + "]");
}
this.resolvableDependencies.put(dependencyType, autowiredValue);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -317,7 +317,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
/**
* Callback before singleton creation.
* <p>Default implementation register the singleton as currently in creation.
* <p>The default implementation register the singleton as currently in creation.
* @param beanName the name of the singleton about to be created
* @see #isSingletonCurrentlyInCreation
*/
@@ -539,13 +539,13 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
}
/**
* Expose the singleton mutex to subclasses.
* Exposes the singleton mutex to subclasses and external collaborators.
* <p>Subclasses should synchronize on the given Object if they perform
* any sort of extended singleton creation phase. In particular, subclasses
* should <i>not</i> have their own mutexes involved in singleton creation,
* to avoid the potential for deadlocks in lazy-init situations.
*/
protected final Object getSingletonMutex() {
public final Object getSingletonMutex() {
return this.singletonObjects;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -97,6 +97,7 @@ public class CustomBooleanEditor extends PropertyEditorSupport {
this.allowEmpty = allowEmpty;
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
String input = (text != null ? text.trim() : null);
@@ -104,20 +105,20 @@ public class CustomBooleanEditor extends PropertyEditorSupport {
// Treat empty String as null value.
setValue(null);
}
else if (this.trueString != null && input.equalsIgnoreCase(this.trueString)) {
else if (this.trueString != null && this.trueString.equalsIgnoreCase(input)) {
setValue(Boolean.TRUE);
}
else if (this.falseString != null && input.equalsIgnoreCase(this.falseString)) {
else if (this.falseString != null && this.falseString.equalsIgnoreCase(input)) {
setValue(Boolean.FALSE);
}
else if (this.trueString == null &&
(input.equalsIgnoreCase(VALUE_TRUE) || input.equalsIgnoreCase(VALUE_ON) ||
input.equalsIgnoreCase(VALUE_YES) || input.equals(VALUE_1))) {
(VALUE_TRUE.equalsIgnoreCase(input) || VALUE_ON.equalsIgnoreCase(input) ||
VALUE_YES.equalsIgnoreCase(input) || VALUE_1.equals(input))) {
setValue(Boolean.TRUE);
}
else if (this.falseString == null &&
(input.equalsIgnoreCase(VALUE_FALSE) || input.equalsIgnoreCase(VALUE_OFF) ||
input.equalsIgnoreCase(VALUE_NO) || input.equals(VALUE_0))) {
(VALUE_FALSE.equalsIgnoreCase(input) || VALUE_OFF.equalsIgnoreCase(input) ||
VALUE_NO.equalsIgnoreCase(input) || VALUE_0.equals(input))) {
setValue(Boolean.FALSE);
}
else {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -917,6 +917,15 @@ public class ExtendedBeanInfoTests {
}
}
@Test // SPR-12434
public void shouldDetectValidPropertiesAndIgnoreInvalidProperties() throws IntrospectionException {
BeanInfo bi = new ExtendedBeanInfo(Introspector.getBeanInfo(java.awt.Window.class));
assertThat(hasReadMethodForProperty(bi, "locationByPlatform"), is(true));
assertThat(hasWriteMethodForProperty(bi, "locationByPlatform"), is(true));
assertThat(hasIndexedReadMethodForProperty(bi, "locationByPlatform"), is(false));
assertThat(hasIndexedWriteMethodForProperty(bi, "locationByPlatform"), is(false));
}
interface Spr9453<T> {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,18 +16,13 @@
package org.springframework.beans.factory;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.springframework.tests.TestResourceUtils.qualifiedResource;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.StaticListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
@@ -39,6 +34,8 @@ import org.springframework.tests.sample.beans.TestBean;
import org.springframework.tests.sample.beans.factory.DummyFactory;
import org.springframework.util.ObjectUtils;
import static org.junit.Assert.*;
import static org.springframework.tests.TestResourceUtils.*;
/**
* @author Rod Johnson
@@ -54,16 +51,16 @@ public final class BeanFactoryUtilsTests {
private static final Resource LEAF_CONTEXT = qualifiedResource(CLASS, "leaf.xml");
private static final Resource DEPENDENT_BEANS_CONTEXT = qualifiedResource(CLASS, "dependentBeans.xml");
private ConfigurableListableBeanFactory listableBeanFactory;
private DefaultListableBeanFactory listableBeanFactory;
private DefaultListableBeanFactory dependentBeansFactory;
private ConfigurableListableBeanFactory dependentBeansBF;
@Before
public void setUp() {
// Interesting hierarchical factory to test counts.
// Slow to read so we cache it.
DefaultListableBeanFactory grandParent = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(grandParent).loadBeanDefinitions(ROOT_CONTEXT);
DefaultListableBeanFactory parent = new DefaultListableBeanFactory(grandParent);
@@ -71,12 +68,13 @@ public final class BeanFactoryUtilsTests {
DefaultListableBeanFactory child = new DefaultListableBeanFactory(parent);
new XmlBeanDefinitionReader(child).loadBeanDefinitions(LEAF_CONTEXT);
this.dependentBeansBF = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader((BeanDefinitionRegistry) this.dependentBeansBF).loadBeanDefinitions(DEPENDENT_BEANS_CONTEXT);
dependentBeansBF.preInstantiateSingletons();
this.dependentBeansFactory = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(this.dependentBeansFactory).loadBeanDefinitions(DEPENDENT_BEANS_CONTEXT);
dependentBeansFactory.preInstantiateSingletons();
this.listableBeanFactory = child;
}
@Test
public void testHierarchicalCountBeansWithNonHierarchicalFactory() {
StaticListableBeanFactory lbf = new StaticListableBeanFactory();
@@ -93,22 +91,21 @@ public final class BeanFactoryUtilsTests {
// Leaf count
assertTrue(this.listableBeanFactory.getBeanDefinitionCount() == 1);
// Count minus duplicate
assertTrue("Should count 7 beans, not "
+ BeanFactoryUtils.countBeansIncludingAncestors(this.listableBeanFactory),
BeanFactoryUtils.countBeansIncludingAncestors(this.listableBeanFactory) == 7);
assertTrue("Should count 7 beans, not " + BeanFactoryUtils.countBeansIncludingAncestors(this.listableBeanFactory),
BeanFactoryUtils.countBeansIncludingAncestors(this.listableBeanFactory) == 7);
}
@Test
public void testHierarchicalNamesWithNoMatch() throws Exception {
List<String> names = Arrays.asList(BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.listableBeanFactory,
NoOp.class));
List<String> names = Arrays.asList(
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.listableBeanFactory, NoOp.class));
assertEquals(0, names.size());
}
@Test
public void testHierarchicalNamesWithMatchOnlyInRoot() throws Exception {
List<String> names = Arrays.asList(BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.listableBeanFactory,
IndexedTestBean.class));
List<String> names = Arrays.asList(
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.listableBeanFactory, IndexedTestBean.class));
assertEquals(1, names.size());
assertTrue(names.contains("indexedBean"));
// Distinguish from default ListableBeanFactory behavior
@@ -117,8 +114,8 @@ public final class BeanFactoryUtilsTests {
@Test
public void testGetBeanNamesForTypeWithOverride() throws Exception {
List<String> names = Arrays.asList(BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.listableBeanFactory,
ITestBean.class));
List<String> names = Arrays.asList(
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.listableBeanFactory, ITestBean.class));
// includes 2 TestBeans from FactoryBeans (DummyFactory definitions)
assertEquals(4, names.size());
assertTrue(names.contains("test"));
@@ -131,7 +128,7 @@ public final class BeanFactoryUtilsTests {
public void testNoBeansOfType() {
StaticListableBeanFactory lbf = new StaticListableBeanFactory();
lbf.addBean("foo", new Object());
Map<?, ?> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(lbf, ITestBean.class, true, false);
Map<String, ?> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(lbf, ITestBean.class, true, false);
assertTrue(beans.isEmpty());
}
@@ -148,7 +145,7 @@ public final class BeanFactoryUtilsTests {
lbf.addBean("t3", t3);
lbf.addBean("t4", t4);
Map<?, ?> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(lbf, ITestBean.class, true, false);
Map<String, ?> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(lbf, ITestBean.class, true, false);
assertEquals(2, beans.size());
assertEquals(t1, beans.get("t1"));
assertEquals(t2, beans.get("t2"));
@@ -192,8 +189,8 @@ public final class BeanFactoryUtilsTests {
this.listableBeanFactory.registerSingleton("t3", t3);
this.listableBeanFactory.registerSingleton("t4", t4);
Map<?, ?> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.listableBeanFactory, ITestBean.class, true,
false);
Map<String, ?> beans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(this.listableBeanFactory, ITestBean.class, true, false);
assertEquals(6, beans.size());
assertEquals(test3, beans.get("test3"));
assertEquals(test, beans.get("test"));
@@ -201,12 +198,9 @@ public final class BeanFactoryUtilsTests {
assertEquals(t2, beans.get("t2"));
assertEquals(t3.getObject(), beans.get("t3"));
assertTrue(beans.get("t4") instanceof TestBean);
// t3 and t4 are found here as of Spring 2.0, since they are
// pre-registered
// singleton instances, while testFactory1 and testFactory are *not*
// found
// because they are FactoryBean definitions that haven't been
// initialized yet.
// t3 and t4 are found here as of Spring 2.0, since they are pre-registered
// singleton instances, while testFactory1 and testFactory are *not* found
// because they are FactoryBean definitions that haven't been initialized yet.
beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.listableBeanFactory, ITestBean.class, false, true);
Object testFactory1 = this.listableBeanFactory.getBean("testFactory1");
@@ -248,8 +242,8 @@ public final class BeanFactoryUtilsTests {
Object test3 = this.listableBeanFactory.getBean("test3");
Object test = this.listableBeanFactory.getBean("test");
Map<?, ?> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.listableBeanFactory, ITestBean.class, true,
false);
Map<String, ?> beans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(this.listableBeanFactory, ITestBean.class, true, false);
assertEquals(2, beans.size());
assertEquals(test3, beans.get("test3"));
assertEquals(test, beans.get("test"));
@@ -284,25 +278,25 @@ public final class BeanFactoryUtilsTests {
@Test
public void testADependencies() {
String[] deps = this.dependentBeansBF.getDependentBeans("a");
String[] deps = this.dependentBeansFactory.getDependentBeans("a");
assertTrue(ObjectUtils.isEmpty(deps));
}
@Test
public void testBDependencies() {
String[] deps = this.dependentBeansBF.getDependentBeans("b");
String[] deps = this.dependentBeansFactory.getDependentBeans("b");
assertTrue(Arrays.equals(new String[] { "c" }, deps));
}
@Test
public void testCDependencies() {
String[] deps = this.dependentBeansBF.getDependentBeans("c");
String[] deps = this.dependentBeansFactory.getDependentBeans("c");
assertTrue(Arrays.equals(new String[] { "int", "long" }, deps));
}
@Test
public void testIntDependencies() {
String[] deps = this.dependentBeansBF.getDependentBeans("int");
String[] deps = this.dependentBeansFactory.getDependentBeans("int");
assertTrue(Arrays.equals(new String[] { "buffer" }, deps));
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,7 +32,6 @@ import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import javax.security.auth.Subject;
import org.apache.commons.logging.Log;
@@ -41,6 +40,7 @@ import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.NotWritablePropertyException;
@@ -104,9 +104,11 @@ public class DefaultListableBeanFactoryTests {
private static final Log factoryLog = LogFactory.getLog(DefaultListableBeanFactory.class);
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void testUnreferencedSingletonWasInstantiated() {
KnowsIfInstantiated.clearInstantiationRecord();
@@ -188,7 +190,7 @@ public class DefaultListableBeanFactoryTests {
}
@Test
public void testPrototypeSingletonFactoryBeanIgnoredByNonEagerTypeMatching() {
public void testSingletonFactoryBeanIgnoredByNonEagerTypeMatching() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
Properties p = new Properties();
p.setProperty("x1.(class)", DummyFactory.class.getName());
@@ -1210,8 +1212,8 @@ public class DefaultListableBeanFactoryTests {
}
catch (UnsatisfiedDependencyException ex) {
// expected
assertTrue(ex.getMessage().indexOf("rod") != -1);
assertTrue(ex.getMessage().indexOf("rod2") != -1);
assertTrue(ex.getMessage().contains("rod"));
assertTrue(ex.getMessage().contains("rod2"));
}
}
@@ -1281,13 +1283,13 @@ public class DefaultListableBeanFactoryTests {
assertNull(bean.getSpouse());
}
@Test(expected=NoSuchBeanDefinitionException.class)
@Test(expected = NoSuchBeanDefinitionException.class)
public void testGetBeanByTypeWithNoneFound() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
lbf.getBean(TestBean.class);
}
@Test(expected=NoUniqueBeanDefinitionException.class)
@Test(expected = NoUniqueBeanDefinitionException.class)
public void testGetBeanByTypeWithAmbiguity() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
@@ -1391,7 +1393,7 @@ public class DefaultListableBeanFactoryTests {
* Java method names. In other words, you can't name a method
* {@code set&amp;FactoryBean(...)}.
*/
@Test(expected=TypeMismatchException.class)
@Test(expected = TypeMismatchException.class)
public void testAutowireBeanWithFactoryBeanByName() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd = new RootBeanDefinition(LazyInitFactory.class);
@@ -1414,8 +1416,8 @@ public class DefaultListableBeanFactoryTests {
}
catch (UnsatisfiedDependencyException ex) {
// expected
assertTrue(ex.getMessage().indexOf("test") != -1);
assertTrue(ex.getMessage().indexOf("spouse") != -1);
assertTrue(ex.getMessage().contains("test"));
assertTrue(ex.getMessage().contains("spouse"));
}
}
@@ -1432,8 +1434,8 @@ public class DefaultListableBeanFactoryTests {
}
catch (UnsatisfiedDependencyException ex) {
// expected
assertTrue(ex.getMessage().indexOf("test") != -1);
assertTrue(ex.getMessage().indexOf("spouse") != -1);
assertTrue(ex.getMessage().contains("test"));
assertTrue(ex.getMessage().contains("spouse"));
}
}
@@ -1681,7 +1683,7 @@ public class DefaultListableBeanFactoryTests {
}
catch (BeanCreationException ex) {
assertEquals("test", ex.getBeanName());
assertTrue(ex.getMessage().toLowerCase().indexOf("interface") != -1);
assertTrue(ex.getMessage().toLowerCase().contains("interface"));
}
}
@@ -1695,7 +1697,7 @@ public class DefaultListableBeanFactoryTests {
}
catch (BeanCreationException ex) {
assertEquals("test", ex.getBeanName());
assertTrue(ex.getMessage().toLowerCase().indexOf("abstract") != -1);
assertTrue(ex.getMessage().toLowerCase().contains("abstract"));
}
}
@@ -2142,13 +2144,13 @@ public class DefaultListableBeanFactoryTests {
assertEquals(expectedNameFromArgs, tb2.getName());
}
@Test(expected=IllegalStateException.class)
@Test(expected = IllegalStateException.class)
public void testScopingBeanToUnregisteredScopeResultsInAnException() throws Exception {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(TestBean.class);
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
beanDefinition.setScope("he put himself so low could hardly look me in the face");
final DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
factory.registerBeanDefinition("testBean", beanDefinition);
factory.getBean("testBean");
}
@@ -2160,8 +2162,7 @@ public class DefaultListableBeanFactoryTests {
RootBeanDefinition parent = new RootBeanDefinition();
parent.setScope(RootBeanDefinition.SCOPE_PROTOTYPE);
AbstractBeanDefinition child = BeanDefinitionBuilder
.childBeanDefinition("parent").getBeanDefinition();
AbstractBeanDefinition child = BeanDefinitionBuilder.childBeanDefinition("parent").getBeanDefinition();
child.setBeanClass(TestBean.class);
child.setScope(theChildScope);
@@ -2676,6 +2677,7 @@ public class DefaultListableBeanFactoryTests {
}
}
@SuppressWarnings("unused")
private static class KnowsIfInstantiated {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,15 +16,6 @@
package org.springframework.beans.factory.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.genericBeanDefinition;
import static org.springframework.tests.TestResourceUtils.qualifiedResource;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -36,8 +27,8 @@ import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
import java.util.prefs.PreferencesFactory;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.BeanInitializationException;
@@ -52,19 +43,22 @@ import org.springframework.core.io.Resource;
import org.springframework.tests.sample.beans.IndexedTestBean;
import org.springframework.tests.sample.beans.TestBean;
import static org.junit.Assert.*;
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.*;
import static org.springframework.tests.TestResourceUtils.*;
/**
* Unit tests for various {@link PropertyResourceConfigurer} implementations including:
* {@link PropertyPlaceholderConfigurer}, {@link PropertyOverrideConfigurer} and
* {@link PreferencesPlaceholderConfigurer}.
*
* @see PropertyPlaceholderConfigurerTests
* @since 02.10.2003
* @author Juergen Hoeller
* @author Chris Beams
* @author Phillip Webb
* @since 02.10.2003
* @see PropertyPlaceholderConfigurerTests
*/
public final class PropertyResourceConfigurerTests {
public class PropertyResourceConfigurerTests {
static {
System.setProperty("java.util.prefs.PreferencesFactory", MockPreferencesFactory.class.getName());
@@ -75,23 +69,15 @@ public final class PropertyResourceConfigurerTests {
private static final Resource XTEST_PROPS = qualifiedResource(CLASS, "xtest.properties"); // does not exist
private static final Resource TEST_PROPS_XML = qualifiedResource(CLASS, "test.properties.xml");
private DefaultListableBeanFactory factory;
private final DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
@Before
public void setUp() {
factory = new DefaultListableBeanFactory();
}
@Test
public void testPropertyOverrideConfigurer() {
BeanDefinition def1 = BeanDefinitionBuilder
.genericBeanDefinition(TestBean.class)
.getBeanDefinition();
BeanDefinition def1 = BeanDefinitionBuilder.genericBeanDefinition(TestBean.class).getBeanDefinition();
factory.registerBeanDefinition("tb1", def1);
BeanDefinition def2 = BeanDefinitionBuilder
.genericBeanDefinition(TestBean.class)
.getBeanDefinition();
BeanDefinition def2 = BeanDefinitionBuilder.genericBeanDefinition(TestBean.class).getBeanDefinition();
factory.registerBeanDefinition("tb2", def2);
PropertyOverrideConfigurer poc1;
@@ -128,9 +114,7 @@ public final class PropertyResourceConfigurerTests {
@Test
public void testPropertyOverrideConfigurerWithNestedProperty() {
BeanDefinition def = BeanDefinitionBuilder
.genericBeanDefinition(IndexedTestBean.class)
.getBeanDefinition();
BeanDefinition def = BeanDefinitionBuilder.genericBeanDefinition(IndexedTestBean.class).getBeanDefinition();
factory.registerBeanDefinition("tb", def);
PropertyOverrideConfigurer poc;
@@ -148,9 +132,7 @@ public final class PropertyResourceConfigurerTests {
@Test
public void testPropertyOverrideConfigurerWithNestedPropertyAndDotInBeanName() {
BeanDefinition def = BeanDefinitionBuilder
.genericBeanDefinition(IndexedTestBean.class)
.getBeanDefinition();
BeanDefinition def = BeanDefinitionBuilder.genericBeanDefinition(IndexedTestBean.class).getBeanDefinition();
factory.registerBeanDefinition("my.tb", def);
PropertyOverrideConfigurer poc;
@@ -169,9 +151,7 @@ public final class PropertyResourceConfigurerTests {
@Test
public void testPropertyOverrideConfigurerWithNestedMapPropertyAndDotInMapKey() {
BeanDefinition def = BeanDefinitionBuilder
.genericBeanDefinition(IndexedTestBean.class)
.getBeanDefinition();
BeanDefinition def = BeanDefinitionBuilder.genericBeanDefinition(IndexedTestBean.class).getBeanDefinition();
factory.registerBeanDefinition("tb", def);
PropertyOverrideConfigurer poc;
@@ -189,9 +169,7 @@ public final class PropertyResourceConfigurerTests {
@Test
public void testPropertyOverrideConfigurerWithHeldProperties() {
BeanDefinition def = BeanDefinitionBuilder
.genericBeanDefinition(PropertiesHolder.class)
.getBeanDefinition();
BeanDefinition def = BeanDefinitionBuilder.genericBeanDefinition(PropertiesHolder.class).getBeanDefinition();
factory.registerBeanDefinition("tb", def);
PropertyOverrideConfigurer poc;
@@ -205,23 +183,9 @@ public final class PropertyResourceConfigurerTests {
assertEquals("true", tb.getHeldProperties().getProperty("mail.smtp.auth"));
}
static class PropertiesHolder {
private Properties props = new Properties();
public Properties getHeldProperties() {
return props;
}
public void setHeldProperties(Properties props) {
this.props = props;
}
}
@Test
public void testPropertyOverrideConfigurerWithPropertiesFile() {
BeanDefinition def = BeanDefinitionBuilder
.genericBeanDefinition(IndexedTestBean.class)
.getBeanDefinition();
BeanDefinition def = BeanDefinitionBuilder.genericBeanDefinition(IndexedTestBean.class).getBeanDefinition();
factory.registerBeanDefinition("tb", def);
PropertyOverrideConfigurer poc = new PropertyOverrideConfigurer();
@@ -235,13 +199,11 @@ public final class PropertyResourceConfigurerTests {
@Test
public void testPropertyOverrideConfigurerWithInvalidPropertiesFile() {
BeanDefinition def = BeanDefinitionBuilder
.genericBeanDefinition(IndexedTestBean.class)
.getBeanDefinition();
BeanDefinition def = BeanDefinitionBuilder.genericBeanDefinition(IndexedTestBean.class).getBeanDefinition();
factory.registerBeanDefinition("tb", def);
PropertyOverrideConfigurer poc = new PropertyOverrideConfigurer();
poc.setLocations(new Resource[] { TEST_PROPS, XTEST_PROPS });
poc.setLocations(TEST_PROPS, XTEST_PROPS);
poc.setIgnoreResourceNotFound(true);
poc.postProcessBeanFactory(factory);
@@ -252,9 +214,7 @@ public final class PropertyResourceConfigurerTests {
@Test
public void testPropertyOverrideConfigurerWithPropertiesXmlFile() {
BeanDefinition def = BeanDefinitionBuilder
.genericBeanDefinition(IndexedTestBean.class)
.getBeanDefinition();
BeanDefinition def = BeanDefinitionBuilder.genericBeanDefinition(IndexedTestBean.class).getBeanDefinition();
factory.registerBeanDefinition("tb", def);
PropertyOverrideConfigurer poc = new PropertyOverrideConfigurer();
@@ -268,9 +228,7 @@ public final class PropertyResourceConfigurerTests {
@Test
public void testPropertyOverrideConfigurerWithConvertProperties() {
BeanDefinition def = BeanDefinitionBuilder
.genericBeanDefinition(IndexedTestBean.class)
.getBeanDefinition();
BeanDefinition def = BeanDefinitionBuilder.genericBeanDefinition(IndexedTestBean.class).getBeanDefinition();
factory.registerBeanDefinition("tb", def);
ConvertingOverrideConfigurer bfpp = new ConvertingOverrideConfigurer();
@@ -394,7 +352,6 @@ public final class PropertyResourceConfigurerTests {
cas.addGenericArgumentValue("${var}name${age}");
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("stringArray", new String[] {"${os.name}", "${age}"});
List<Object> friends = new ManagedList<Object>();
@@ -414,7 +371,7 @@ public final class PropertyResourceConfigurerTests {
someMap.put("key1", new RuntimeBeanReference("${ref}"));
someMap.put("key2", "${age}name");
MutablePropertyValues innerPvs = new MutablePropertyValues();
innerPvs.add("touchy", "${os.name}");
innerPvs.add("country", "${os.name}");
RootBeanDefinition innerBd = new RootBeanDefinition(TestBean.class);
innerBd.setPropertyValues(innerPvs);
someMap.put("key3", innerBd);
@@ -464,30 +421,28 @@ public final class PropertyResourceConfigurerTests {
TestBean inner2 = (TestBean) tb2.getSomeMap().get("mykey4");
assertEquals(0, inner1.getAge());
assertEquals(null, inner1.getName());
assertEquals(System.getProperty("os.name"), inner1.getTouchy());
assertEquals(System.getProperty("os.name"), inner1.getCountry());
assertEquals(98, inner2.getAge());
assertEquals("namemyvarmyvar${", inner2.getName());
assertEquals(System.getProperty("os.name"), inner2.getTouchy());
assertEquals(System.getProperty("os.name"), inner2.getCountry());
}
@Test
public void testPropertyPlaceholderConfigurerWithSystemPropertyFallback() {
factory.registerBeanDefinition("tb",
genericBeanDefinition(TestBean.class)
.addPropertyValue("touchy", "${os.name}").getBeanDefinition());
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
.addPropertyValue("country", "${os.name}").getBeanDefinition());
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
ppc.postProcessBeanFactory(factory);
TestBean tb = (TestBean) factory.getBean("tb");
assertEquals(System.getProperty("os.name"), tb.getTouchy());
assertEquals(System.getProperty("os.name"), tb.getCountry());
}
@Test
public void testPropertyPlaceholderConfigurerWithSystemPropertyNotUsed() {
factory.registerBeanDefinition("tb",
genericBeanDefinition(TestBean.class)
.addPropertyValue("touchy", "${os.name}").getBeanDefinition());
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
.addPropertyValue("country", "${os.name}").getBeanDefinition());
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
Properties props = new Properties();
@@ -496,14 +451,13 @@ public final class PropertyResourceConfigurerTests {
ppc.postProcessBeanFactory(factory);
TestBean tb = (TestBean) factory.getBean("tb");
assertEquals("myos", tb.getTouchy());
assertEquals("myos", tb.getCountry());
}
@Test
public void testPropertyPlaceholderConfigurerWithOverridingSystemProperty() {
factory.registerBeanDefinition("tb",
genericBeanDefinition(TestBean.class)
.addPropertyValue("touchy", "${os.name}").getBeanDefinition());
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
.addPropertyValue("country", "${os.name}").getBeanDefinition());
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
Properties props = new Properties();
@@ -513,14 +467,13 @@ public final class PropertyResourceConfigurerTests {
ppc.postProcessBeanFactory(factory);
TestBean tb = (TestBean) factory.getBean("tb");
assertEquals(System.getProperty("os.name"), tb.getTouchy());
assertEquals(System.getProperty("os.name"), tb.getCountry());
}
@Test
public void testPropertyPlaceholderConfigurerWithUnresolvableSystemProperty() {
factory.registerBeanDefinition("tb",
genericBeanDefinition(TestBean.class)
.addPropertyValue("touchy", "${user.dir}").getBeanDefinition());
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
.addPropertyValue("touchy", "${user.dir}").getBeanDefinition());
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
ppc.setSystemPropertiesMode(PropertyPlaceholderConfigurer.SYSTEM_PROPERTIES_MODE_NEVER);
@@ -537,9 +490,8 @@ public final class PropertyResourceConfigurerTests {
@Test
public void testPropertyPlaceholderConfigurerWithUnresolvablePlaceholder() {
factory.registerBeanDefinition("tb",
genericBeanDefinition(TestBean.class)
.addPropertyValue("name", "${ref}").getBeanDefinition());
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
.addPropertyValue("name", "${ref}").getBeanDefinition());
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
@@ -555,9 +507,8 @@ public final class PropertyResourceConfigurerTests {
@Test
public void testPropertyPlaceholderConfigurerWithIgnoreUnresolvablePlaceholder() {
factory.registerBeanDefinition("tb",
genericBeanDefinition(TestBean.class)
.addPropertyValue("name", "${ref}").getBeanDefinition());
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
.addPropertyValue("name", "${ref}").getBeanDefinition());
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
ppc.setIgnoreUnresolvablePlaceholders(true);
@@ -569,9 +520,8 @@ public final class PropertyResourceConfigurerTests {
@Test
public void testPropertyPlaceholderConfigurerWithEmptyStringAsNull() {
factory.registerBeanDefinition("tb",
genericBeanDefinition(TestBean.class)
.addPropertyValue("name", "").getBeanDefinition());
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
.addPropertyValue("name", "").getBeanDefinition());
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
ppc.setNullValue("");
@@ -583,9 +533,8 @@ public final class PropertyResourceConfigurerTests {
@Test
public void testPropertyPlaceholderConfigurerWithEmptyStringInPlaceholderAsNull() {
factory.registerBeanDefinition("tb",
genericBeanDefinition(TestBean.class)
.addPropertyValue("name", "${ref}").getBeanDefinition());
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
.addPropertyValue("name", "${ref}").getBeanDefinition());
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
ppc.setNullValue("");
@@ -600,9 +549,8 @@ public final class PropertyResourceConfigurerTests {
@Test
public void testPropertyPlaceholderConfigurerWithNestedPlaceholderInKey() {
factory.registerBeanDefinition("tb",
genericBeanDefinition(TestBean.class)
.addPropertyValue("name", "${my${key}key}").getBeanDefinition());
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
.addPropertyValue("name", "${my${key}key}").getBeanDefinition());
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
Properties props = new Properties();
@@ -617,8 +565,7 @@ public final class PropertyResourceConfigurerTests {
@Test
public void testPropertyPlaceholderConfigurerWithPlaceholderInAlias() {
factory.registerBeanDefinition("tb",
genericBeanDefinition(TestBean.class).getBeanDefinition());
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class).getBeanDefinition());
factory.registerAlias("tb", "${alias}");
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
@@ -634,8 +581,7 @@ public final class PropertyResourceConfigurerTests {
@Test
public void testPropertyPlaceholderConfigurerWithSelfReferencingPlaceholderInAlias() {
factory.registerBeanDefinition("tb",
genericBeanDefinition(TestBean.class).getBeanDefinition());
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class).getBeanDefinition());
factory.registerAlias("tb", "${alias}");
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
@@ -651,11 +597,10 @@ public final class PropertyResourceConfigurerTests {
@Test
public void testPropertyPlaceholderConfigurerWithCircularReference() {
factory.registerBeanDefinition("tb",
genericBeanDefinition(TestBean.class)
.addPropertyValue("age", "${age}")
.addPropertyValue("name", "name${var}")
.getBeanDefinition());
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
.addPropertyValue("age", "${age}")
.addPropertyValue("name", "name${var}")
.getBeanDefinition());
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
Properties props = new Properties();
@@ -675,9 +620,8 @@ public final class PropertyResourceConfigurerTests {
@Test
public void testPropertyPlaceholderConfigurerWithDefaultProperties() {
factory.registerBeanDefinition("tb",
genericBeanDefinition(TestBean.class)
.addPropertyValue("touchy", "${test}").getBeanDefinition());
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
.addPropertyValue("touchy", "${test}").getBeanDefinition());
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
Properties props = new Properties();
@@ -691,9 +635,8 @@ public final class PropertyResourceConfigurerTests {
@Test
public void testPropertyPlaceholderConfigurerWithInlineDefault() {
factory.registerBeanDefinition("tb",
genericBeanDefinition(TestBean.class)
.addPropertyValue("touchy", "${test:mytest}").getBeanDefinition());
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
.addPropertyValue("touchy", "${test:mytest}").getBeanDefinition());
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
ppc.postProcessBeanFactory(factory);
@@ -704,9 +647,8 @@ public final class PropertyResourceConfigurerTests {
@Test
public void testPropertyPlaceholderConfigurerWithAliases() {
factory.registerBeanDefinition("tb",
genericBeanDefinition(TestBean.class)
.addPropertyValue("touchy", "${test}").getBeanDefinition());
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
.addPropertyValue("touchy", "${test}").getBeanDefinition());
factory.registerAlias("tb", "${myAlias}");
factory.registerAlias("${myTarget}", "alias2");
@@ -729,12 +671,11 @@ public final class PropertyResourceConfigurerTests {
@Test
public void testPreferencesPlaceholderConfigurer() {
factory.registerBeanDefinition("tb",
genericBeanDefinition(TestBean.class)
.addPropertyValue("name", "${myName}")
.addPropertyValue("age", "${myAge}")
.addPropertyValue("touchy", "${myTouchy}")
.getBeanDefinition());
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
.addPropertyValue("name", "${myName}")
.addPropertyValue("age", "${myAge}")
.addPropertyValue("touchy", "${myTouchy}")
.getBeanDefinition());
PreferencesPlaceholderConfigurer ppc = new PreferencesPlaceholderConfigurer();
Properties props = new Properties();
@@ -757,12 +698,11 @@ public final class PropertyResourceConfigurerTests {
@Test
public void testPreferencesPlaceholderConfigurerWithCustomTreePaths() {
factory.registerBeanDefinition("tb",
genericBeanDefinition(TestBean.class)
.addPropertyValue("name", "${myName}")
.addPropertyValue("age", "${myAge}")
.addPropertyValue("touchy", "${myTouchy}")
.getBeanDefinition());
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
.addPropertyValue("name", "${myName}")
.addPropertyValue("age", "${myAge}")
.addPropertyValue("touchy", "${myTouchy}")
.getBeanDefinition());
PreferencesPlaceholderConfigurer ppc = new PreferencesPlaceholderConfigurer();
Properties props = new Properties();
@@ -787,12 +727,11 @@ public final class PropertyResourceConfigurerTests {
@Test
public void testPreferencesPlaceholderConfigurerWithPathInPlaceholder() {
factory.registerBeanDefinition("tb",
genericBeanDefinition(TestBean.class)
.addPropertyValue("name", "${mypath/myName}")
.addPropertyValue("age", "${myAge}")
.addPropertyValue("touchy", "${myotherpath/myTouchy}")
.getBeanDefinition());
factory.registerBeanDefinition("tb", genericBeanDefinition(TestBean.class)
.addPropertyValue("name", "${mypath/myName}")
.addPropertyValue("age", "${myAge}")
.addPropertyValue("touchy", "${myotherpath/myTouchy}")
.getBeanDefinition());
PreferencesPlaceholderConfigurer ppc = new PreferencesPlaceholderConfigurer();
Properties props = new Properties();
@@ -816,6 +755,20 @@ public final class PropertyResourceConfigurerTests {
}
static class PropertiesHolder {
private Properties props = new Properties();
public Properties getHeldProperties() {
return props;
}
public void setHeldProperties(Properties props) {
this.props = props;
}
}
private static class ConvertingOverrideConfigurer extends PropertyOverrideConfigurer {
@Override
@@ -824,26 +777,28 @@ public final class PropertyResourceConfigurerTests {
}
}
/**
* {@link PreferencesFactory} to create {@link MockPreferences}.
*/
public static class MockPreferencesFactory implements PreferencesFactory {
private Preferences systemRoot = new MockPreferences();
private final Preferences userRoot = new MockPreferences();
private Preferences userRoot = new MockPreferences();
private final Preferences systemRoot = new MockPreferences();
@Override
public Preferences systemRoot() {
return systemRoot;
return this.systemRoot;
}
@Override
public Preferences userRoot() {
return userRoot;
return this.userRoot;
}
}
/**
* Mock implementation of {@link Preferences} that behaves the same regardless of the
* underlying operating system and will never throw security exceptions.
@@ -909,4 +864,5 @@ public final class PropertyResourceConfigurerTests {
protected void flushSpi() throws BackingStoreException {
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -59,7 +59,6 @@ import org.springframework.tests.sample.beans.TestBean;
* @author Rob Harrop
* @author Arjen Poutsma
* @author Chris Beams
*
* @since 10.06.2003
*/
public class CustomEditorTests {
@@ -302,8 +301,8 @@ public class CustomEditorTests {
@Test
public void testCustomBooleanEditorWithSpecialTrueAndFalseStrings() throws Exception {
final String trueString = "pechorin";
final String falseString = "nash";
String trueString = "pechorin";
String falseString = "nash";
CustomBooleanEditor editor = new CustomBooleanEditor(trueString, falseString, false);
@@ -320,6 +319,14 @@ public class CustomEditorTests {
editor.setAsText(falseString.toUpperCase());
assertFalse(((Boolean) editor.getValue()).booleanValue());
assertEquals(falseString, editor.getAsText());
try {
editor.setAsText(null);
fail("Should have thrown IllegalArgumentException");
}
catch (IllegalArgumentException ex) {
// expected
}
}
@Test
@@ -423,7 +430,7 @@ public class CustomEditorTests {
assertTrue("Correct bigDecimal value", new BigDecimal("4.5").equals(tb.getBigDecimal()));
}
@Test(expected=IllegalArgumentException.class)
@Test(expected = IllegalArgumentException.class)
public void testCustomNumberEditorCtorWithNullNumberType() throws Exception {
new CustomNumberEditor(null, true);
}
@@ -543,7 +550,7 @@ public class CustomEditorTests {
assertNull(cb.getMyCharacter());
}
@Test(expected=IllegalArgumentException.class)
@Test(expected = IllegalArgumentException.class)
public void testCharacterEditorSetAsTextWithStringLongerThanOneCharacter() throws Exception {
PropertyEditor charEditor = new CharacterEditor(false);
charEditor.setAsText("ColdWaterCanyon");
@@ -562,7 +569,7 @@ public class CustomEditorTests {
assertEquals(" ", charEditor.getAsText());
}
@Test(expected=IllegalArgumentException.class)
@Test(expected = IllegalArgumentException.class)
public void testCharacterEditorSetAsTextWithNullNotAllowingEmptyAsNull() throws Exception {
PropertyEditor charEditor = new CharacterEditor(false);
charEditor.setAsText(null);
@@ -583,7 +590,7 @@ public class CustomEditorTests {
assertEquals("", classEditor.getAsText());
}
@Test(expected=IllegalArgumentException.class)
@Test(expected = IllegalArgumentException.class)
public void testClassEditorWithNonExistentClass() throws Exception {
PropertyEditor classEditor = new ClassEditor();
classEditor.setAsText("hairdresser.on.Fire");
@@ -685,26 +692,40 @@ public class CustomEditorTests {
@Test
public void testCustomBooleanEditor() {
CustomBooleanEditor editor = new CustomBooleanEditor(false);
editor.setAsText("true");
assertEquals(Boolean.TRUE, editor.getValue());
assertEquals("true", editor.getAsText());
editor.setAsText("false");
assertEquals(Boolean.FALSE, editor.getValue());
assertEquals("false", editor.getAsText());
editor.setValue(null);
assertEquals(null, editor.getValue());
assertEquals("", editor.getAsText());
try {
editor.setAsText(null);
fail("Should have thrown IllegalArgumentException");
}
catch (IllegalArgumentException ex) {
// expected
}
}
@Test
public void testCustomBooleanEditorWithEmptyAsNull() {
CustomBooleanEditor editor = new CustomBooleanEditor(true);
editor.setAsText("true");
assertEquals(Boolean.TRUE, editor.getValue());
assertEquals("true", editor.getAsText());
editor.setAsText("false");
assertEquals(Boolean.FALSE, editor.getValue());
assertEquals("false", editor.getAsText());
editor.setValue(null);
assertEquals(null, editor.getValue());
assertEquals("", editor.getAsText());
@@ -750,7 +771,7 @@ public class CustomEditorTests {
}
catch (IllegalArgumentException ex) {
// expected
assertTrue(ex.getMessage().indexOf("10") != -1);
assertTrue(ex.getMessage().contains("10"));
}
}
@@ -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.
@@ -36,13 +36,15 @@ import org.springframework.beans.factory.parsing.ReaderEventListener;
*/
public class CollectingReaderEventListener implements ReaderEventListener {
private final List defaults = new LinkedList();
private final List<DefaultsDefinition> defaults = new LinkedList<DefaultsDefinition>();
private final Map componentDefinitions = new LinkedHashMap<>(8);
private final Map<String, ComponentDefinition> componentDefinitions =
new LinkedHashMap<String, ComponentDefinition>(8);
private final Map aliasMap = new LinkedHashMap<>(8);
private final Map<String, List<AliasDefinition>> aliasMap =
new LinkedHashMap<String, List<AliasDefinition>>(8);
private final List imports = new LinkedList();
private final List<ImportDefinition> imports = new LinkedList<ImportDefinition>();
@Override
@@ -50,7 +52,7 @@ public class CollectingReaderEventListener implements ReaderEventListener {
this.defaults.add(defaultsDefinition);
}
public List getDefaults() {
public List<DefaultsDefinition> getDefaults() {
return Collections.unmodifiableList(this.defaults);
}
@@ -60,27 +62,27 @@ public class CollectingReaderEventListener implements ReaderEventListener {
}
public ComponentDefinition getComponentDefinition(String name) {
return (ComponentDefinition) this.componentDefinitions.get(name);
return this.componentDefinitions.get(name);
}
public ComponentDefinition[] getComponentDefinitions() {
Collection collection = this.componentDefinitions.values();
return (ComponentDefinition[]) collection.toArray(new ComponentDefinition[collection.size()]);
Collection<ComponentDefinition> collection = this.componentDefinitions.values();
return collection.toArray(new ComponentDefinition[collection.size()]);
}
@Override
public void aliasRegistered(AliasDefinition aliasDefinition) {
List aliases = (List) this.aliasMap.get(aliasDefinition.getBeanName());
if(aliases == null) {
aliases = new ArrayList();
List<AliasDefinition> aliases = this.aliasMap.get(aliasDefinition.getBeanName());
if (aliases == null) {
aliases = new ArrayList<AliasDefinition>();
this.aliasMap.put(aliasDefinition.getBeanName(), aliases);
}
aliases.add(aliasDefinition);
}
public List getAliases(String beanName) {
List aliases = (List) this.aliasMap.get(beanName);
return aliases == null ? null : Collections.unmodifiableList(aliases);
public List<AliasDefinition> getAliases(String beanName) {
List<AliasDefinition> aliases = this.aliasMap.get(beanName);
return (aliases != null ? Collections.unmodifiableList(aliases) : null);
}
@Override
@@ -88,7 +90,7 @@ public class CollectingReaderEventListener implements ReaderEventListener {
this.imports.add(importDefinition);
}
public List getImports() {
public List<ImportDefinition> getImports() {
return Collections.unmodifiableList(this.imports);
}
@@ -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.
@@ -76,13 +76,13 @@ public class TestBean implements BeanNameAware, BeanFactoryAware, ITestBean, IOt
private Float myFloat = new Float(0.0);
private Collection<? super Object> friends = new LinkedList<>();
private Collection<? super Object> friends = new LinkedList<Object>();
private Set<?> someSet = new HashSet<>();
private Set<?> someSet = new HashSet<Object>();
private Map<?, ?> someMap = new HashMap<>();
private Map<?, ?> someMap = new HashMap<Object, Object>();
private List<?> someList = new ArrayList<>();
private List<?> someList = new ArrayList<Object>();
private Properties someProperties = new Properties();
@@ -255,10 +255,12 @@ public class TestBean implements BeanNameAware, BeanFactoryAware, ITestBean, IOt
this.stringArray = stringArray;
}
@Override
public Integer[] getSomeIntegerArray() {
return someIntegerArray;
}
@Override
public void setSomeIntegerArray(Integer[] someIntegerArray) {
this.someIntegerArray = someIntegerArray;
}
@@ -461,6 +463,7 @@ public class TestBean implements BeanNameAware, BeanFactoryAware, ITestBean, IOt
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
@@ -472,6 +475,7 @@ public class TestBean implements BeanNameAware, BeanFactoryAware, ITestBean, IOt
return (ObjectUtils.nullSafeEquals(this.name, tb2.name) && this.age == tb2.age);
}
@Override
public int hashCode() {
return this.age;
}
@@ -486,6 +490,7 @@ public class TestBean implements BeanNameAware, BeanFactoryAware, ITestBean, IOt
}
}
@Override
public String toString() {
return this.name;
}
@@ -15,7 +15,7 @@
<util:property-path id="name" path="
configuredBean.
name
"/>
"/>
<bean id="testBean" class="org.springframework.tests.sample.beans.TestBean" scope="prototype">
<property name="name">
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -126,6 +126,10 @@ public class JCacheCache implements Cache {
@SuppressWarnings("serial")
private static class NullHolder implements Serializable {
private Object readResolve() {
return NULL_HOLDER;
}
}
}
@@ -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.
@@ -126,7 +126,7 @@ public class TimerManagerTaskScheduler extends TimerManagerAccessor implements T
}
public long getDelay(TimeUnit unit) {
return unit.convert(System.currentTimeMillis() - this.timer.getScheduledExecutionTime(), TimeUnit.MILLISECONDS);
return unit.convert(this.timer.getScheduledExecutionTime() - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
public int compareTo(Delayed other) {
@@ -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.
@@ -245,7 +245,9 @@ public class CronTriggerFactoryBean implements FactoryBean<CronTrigger>, BeanNam
CronTriggerImpl cti = new CronTriggerImpl();
cti.setName(this.name);
cti.setGroup(this.group);
cti.setJobKey(this.jobDetail.getKey());
if (this.jobDetail != null) {
cti.setJobKey(this.jobDetail.getKey());
}
cti.setJobDataMap(this.jobDataMap);
cti.setStartTime(this.startTime);
cti.setCronExpression(this.cronExpression);
@@ -274,12 +276,14 @@ public class CronTriggerFactoryBean implements FactoryBean<CronTrigger>, BeanNam
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("name", this.name);
pvs.add("group", this.group);
if (jobKeyMethod != null) {
pvs.add("jobKey", ReflectionUtils.invokeMethod(jobKeyMethod, this.jobDetail));
}
else {
pvs.add("jobName", this.jobDetail.getName());
pvs.add("jobGroup", this.jobDetail.getGroup());
if (this.jobDetail != null) {
if (jobKeyMethod != null) {
pvs.add("jobKey", ReflectionUtils.invokeMethod(jobKeyMethod, this.jobDetail));
}
else {
pvs.add("jobName", this.jobDetail.getName());
pvs.add("jobGroup", this.jobDetail.getGroup());
}
}
pvs.add("jobDataMap", this.jobDataMap);
pvs.add("startTime", this.startTime);
@@ -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.
@@ -16,7 +16,6 @@
package org.springframework.scheduling.quartz;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
@@ -82,32 +81,41 @@ public class ResourceLoaderClassLoadHelper implements ClassLoadHelper {
public URL getResource(String name) {
Resource resource = this.resourceLoader.getResource(name);
try {
return resource.getURL();
if (resource.exists()) {
try {
return resource.getURL();
}
catch (IOException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Could not load " + resource);
}
return null;
}
}
catch (FileNotFoundException ex) {
return null;
}
catch (IOException ex) {
logger.warn("Could not load " + resource);
return null;
else {
return getClassLoader().getResource(name);
}
}
public InputStream getResourceAsStream(String name) {
Resource resource = this.resourceLoader.getResource(name);
try {
return resource.getInputStream();
if (resource.exists()) {
try {
return resource.getInputStream();
}
catch (IOException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Could not load " + resource);
}
return null;
}
}
catch (FileNotFoundException ex) {
return null;
}
catch (IOException ex) {
logger.warn("Could not load " + resource);
return null;
else {
return getClassLoader().getResourceAsStream(name);
}
}
@Override
public ClassLoader getClassLoader() {
return this.resourceLoader.getClassLoader();
}
@@ -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.
@@ -237,7 +237,9 @@ public class SimpleTriggerFactoryBean implements FactoryBean<SimpleTrigger>, Bea
SimpleTriggerImpl sti = new SimpleTriggerImpl();
sti.setName(this.name);
sti.setGroup(this.group);
sti.setJobKey(this.jobDetail.getKey());
if (this.jobDetail != null) {
sti.setJobKey(this.jobDetail.getKey());
}
sti.setJobDataMap(this.jobDataMap);
sti.setStartTime(this.startTime);
sti.setRepeatInterval(this.repeatInterval);
@@ -265,12 +267,14 @@ public class SimpleTriggerFactoryBean implements FactoryBean<SimpleTrigger>, Bea
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("name", this.name);
pvs.add("group", this.group);
if (jobKeyMethod != null) {
pvs.add("jobKey", ReflectionUtils.invokeMethod(jobKeyMethod, this.jobDetail));
}
else {
pvs.add("jobName", this.jobDetail.getName());
pvs.add("jobGroup", this.jobDetail.getGroup());
if (this.jobDetail != null) {
if (jobKeyMethod != null) {
pvs.add("jobKey", ReflectionUtils.invokeMethod(jobKeyMethod, this.jobDetail));
}
else {
pvs.add("jobName", this.jobDetail.getName());
pvs.add("jobGroup", this.jobDetail.getGroup());
}
}
pvs.add("jobDataMap", this.jobDataMap);
pvs.add("startTime", this.startTime);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -45,6 +45,7 @@ public abstract class FreeMarkerTemplateUtils {
*/
public static String processTemplateIntoString(Template template, Object model)
throws IOException, TemplateException {
StringWriter result = new StringWriter();
template.process(model, result);
return result.toString();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,9 +28,9 @@ import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
/**
* FreeMarker TemplateLoader adapter that loads via a Spring ResourceLoader.
* Used by FreeMarkerConfigurationFactory for any resource loader path that
* cannot be resolved to a java.io.File.
* FreeMarker {@link TemplateLoader} adapter that loads via a Spring {@link ResourceLoader}.
* Used by {@link FreeMarkerConfigurationFactory} for any resource loader path that cannot
* be resolved to a {@link java.io.File}.
*
* @author Juergen Hoeller
* @since 14.03.2004
@@ -63,6 +63,7 @@ public class SpringTemplateLoader implements TemplateLoader {
}
}
public Object findTemplateSource(String name) throws IOException {
if (logger.isDebugEnabled()) {
logger.debug("Looking for FreeMarker template with name [" + name + "]");
@@ -84,7 +85,6 @@ public class SpringTemplateLoader implements TemplateLoader {
}
}
public long getLastModified(Object templateSource) {
Resource resource = (Resource) templateSource;
try {
@@ -0,0 +1,41 @@
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.scheduling.quartz;
import java.text.ParseException;
import org.junit.Test;
import org.quartz.CronTrigger;
import static org.junit.Assert.*;
/**
* @author Stephane Nicoll
*/
public class CronTriggerFactoryBeanTests {
@Test
public void createWithoutJobDetail() throws ParseException {
CronTriggerFactoryBean factory = new CronTriggerFactoryBean();
factory.setName("myTrigger");
factory.setCronExpression("0 15 10 ? * *");
factory.afterPropertiesSet();
CronTrigger trigger = factory.getObject();
assertEquals("0 15 10 ? * *", trigger.getCronExpression());
}
}
@@ -0,0 +1,43 @@
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.scheduling.quartz;
import java.text.ParseException;
import org.junit.Test;
import org.quartz.SimpleTrigger;
import static org.junit.Assert.*;
/**
* @author Stephane Nicoll
*/
public class SimpleTriggerFactoryBeanTests {
@Test
public void createWithoutJobDetail() throws ParseException {
SimpleTriggerFactoryBean factory = new SimpleTriggerFactoryBean();
factory.setName("myTrigger");
factory.setRepeatCount(5);
factory.setRepeatInterval(1000L);
factory.afterPropertiesSet();
SimpleTrigger trigger = factory.getObject();
assertEquals(5, trigger.getRepeatCount());
assertEquals(1000L, trigger.getRepeatInterval());
}
}
@@ -1,249 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ui.jasperreports;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import junit.framework.TestCase;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.export.JRCsvExporterParameter;
import net.sf.jasperreports.engine.export.JRExportProgressMonitor;
import net.sf.jasperreports.engine.export.JRHtmlExporter;
import net.sf.jasperreports.engine.export.JRHtmlExporterParameter;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.export.JRPdfExporterParameter;
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
import net.sf.jasperreports.engine.util.JRLoader;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.core.io.ClassPathResource;
/**
* @author Rob Harrop
* @author Juergen Hoeller
* @since 18.11.2004
*/
public class JasperReportsUtilsTests extends TestCase {
public void testRenderAsCsvWithDataSource() throws Exception {
StringWriter writer = new StringWriter();
JasperReportsUtils.renderAsCsv(getReport(), getParameters(), getDataSource(), writer);
String output = writer.getBuffer().toString();
assertCsvOutputCorrect(output);
}
public void testRenderAsCsvWithCollection() throws Exception {
StringWriter writer = new StringWriter();
JasperReportsUtils.renderAsCsv(getReport(), getParameters(), getData(), writer);
String output = writer.getBuffer().toString();
assertCsvOutputCorrect(output);
}
public void testRenderAsCsvWithExporterParameters() throws Exception {
StringWriter writer = new StringWriter();
Map<JRExporterParameter, Object> exporterParameters = new HashMap<JRExporterParameter, Object>();
exporterParameters.put(JRCsvExporterParameter.FIELD_DELIMITER, "~");
JasperReportsUtils.renderAsCsv(getReport(), getParameters(), getData(), writer, exporterParameters);
String output = writer.getBuffer().toString();
assertCsvOutputCorrect(output);
assertTrue("Delimiter is incorrect", output.contains("~"));
}
public void testRenderAsHtmlWithDataSource() throws Exception {
StringWriter writer = new StringWriter();
JasperReportsUtils.renderAsHtml(getReport(), getParameters(), getDataSource(), writer);
String output = writer.getBuffer().toString();
assertHtmlOutputCorrect(output);
}
public void testRenderAsHtmlWithCollection() throws Exception {
StringWriter writer = new StringWriter();
JasperReportsUtils.renderAsHtml(getReport(), getParameters(), getData(), writer);
String output = writer.getBuffer().toString();
assertHtmlOutputCorrect(output);
}
public void testRenderAsHtmlWithExporterParameters() throws Exception {
StringWriter writer = new StringWriter();
Map<JRExporterParameter, Object> exporterParameters = new HashMap<JRExporterParameter, Object>();
String uri = "/my/uri";
exporterParameters.put(JRHtmlExporterParameter.IMAGES_URI, uri);
JasperReportsUtils.renderAsHtml(getReport(), getParameters(), getData(), writer, exporterParameters);
String output = writer.getBuffer().toString();
assertHtmlOutputCorrect(output);
assertTrue("URI not included", output.contains(uri));
}
public void testRenderAsPdfWithDataSource() throws Exception {
ByteArrayOutputStream os = new ByteArrayOutputStream();
JasperReportsUtils.renderAsPdf(getReport(), getParameters(), getDataSource(), os);
byte[] output = os.toByteArray();
assertPdfOutputCorrect(output);
}
public void testRenderAsPdfWithCollection() throws Exception {
ByteArrayOutputStream os = new ByteArrayOutputStream();
JasperReportsUtils.renderAsPdf(getReport(), getParameters(), getData(), os);
byte[] output = os.toByteArray();
assertPdfOutputCorrect(output);
}
public void testRenderAsPdfWithExporterParameters() throws Exception {
ByteArrayOutputStream os = new ByteArrayOutputStream();
Map<JRExporterParameter, Object> exporterParameters = new HashMap<JRExporterParameter, Object>();
exporterParameters.put(JRPdfExporterParameter.PDF_VERSION, JRPdfExporterParameter.PDF_VERSION_1_6);
JasperReportsUtils.renderAsPdf(getReport(), getParameters(), getData(), os, exporterParameters);
byte[] output = os.toByteArray();
assertPdfOutputCorrect(output);
assertTrue(new String(output).contains("PDF-1.6"));
}
public void testRenderAsXlsWithDataSource() throws Exception {
ByteArrayOutputStream os = new ByteArrayOutputStream();
JasperReportsUtils.renderAsXls(getReport(), getParameters(), getDataSource(), os);
byte[] output = os.toByteArray();
assertXlsOutputCorrect(output);
}
public void testRenderAsXlsWithCollection() throws Exception {
ByteArrayOutputStream os = new ByteArrayOutputStream();
JasperReportsUtils.renderAsXls(getReport(), getParameters(), getData(), os);
byte[] output = os.toByteArray();
assertXlsOutputCorrect(output);
}
public void testRenderAsXlsWithExporterParameters() throws Exception {
ByteArrayOutputStream os = new ByteArrayOutputStream();
Map<JRExporterParameter, Object> exporterParameters = new HashMap<JRExporterParameter, Object>();
SimpleProgressMonitor monitor = new SimpleProgressMonitor();
exporterParameters.put(JRXlsExporterParameter.PROGRESS_MONITOR, monitor);
JasperReportsUtils.renderAsXls(getReport(), getParameters(), getData(), os, exporterParameters);
byte[] output = os.toByteArray();
assertXlsOutputCorrect(output);
assertTrue(monitor.isInvoked());
}
public void testRenderWithWriter() throws Exception {
StringWriter writer = new StringWriter();
JasperPrint print = JasperFillManager.fillReport(getReport(), getParameters(), getDataSource());
JasperReportsUtils.render(new JRHtmlExporter(), print, writer);
String output = writer.getBuffer().toString();
assertHtmlOutputCorrect(output);
}
public void testRenderWithOutputStream() throws Exception {
ByteArrayOutputStream os = new ByteArrayOutputStream();
JasperPrint print = JasperFillManager.fillReport(getReport(), getParameters(), getDataSource());
JasperReportsUtils.render(new JRPdfExporter(), print, os);
byte[] output = os.toByteArray();
assertPdfOutputCorrect(output);
}
private void assertCsvOutputCorrect(String output) {
assertTrue("Output length should be greater than 0", (output.length() > 0));
assertTrue("Output should start with Dear Lord!", output.startsWith("Dear Lord!"));
assertTrue("Output should contain 'MeineSeite'", output.contains("MeineSeite"));
}
private void assertHtmlOutputCorrect(String output) {
assertTrue("Output length should be greater than 0", (output.length() > 0));
assertTrue("Output should contain <html>", output.contains("<html>"));
assertTrue("Output should contain 'MeineSeite'", output.contains("MeineSeite"));
}
private void assertPdfOutputCorrect(byte[] output) throws Exception {
assertTrue("Output length should be greater than 0", (output.length > 0));
String translated = new String(output, "US-ASCII");
assertTrue("Output should start with %PDF", translated.startsWith("%PDF"));
}
private void assertXlsOutputCorrect(byte[] output) throws Exception {
HSSFWorkbook workbook = new HSSFWorkbook(new ByteArrayInputStream(output));
HSSFSheet sheet = workbook.getSheetAt(0);
assertNotNull("Sheet should not be null", sheet);
HSSFRow row = sheet.getRow(3);
HSSFCell cell = row.getCell((short) 1);
assertNotNull("Cell should not be null", cell);
assertEquals("Cell content should be Dear Lord!", "Dear Lord!", cell.getRichStringCellValue().getString());
}
private JasperReport getReport() throws Exception {
ClassPathResource resource = new ClassPathResource("DataSourceReport.jasper", getClass());
return (JasperReport) JRLoader.loadObject(resource.getInputStream());
}
private Map<String, Object> getParameters() {
Map<String, Object> model = new HashMap<String, Object>();
model.put("ReportTitle", "Dear Lord!");
model.put(JRParameter.REPORT_LOCALE, Locale.GERMAN);
model.put(JRParameter.REPORT_RESOURCE_BUNDLE,
ResourceBundle.getBundle("org/springframework/ui/jasperreports/messages", Locale.GERMAN));
return model;
}
private JRDataSource getDataSource() {
return new JRBeanCollectionDataSource(getData());
}
private List<PersonBean> getData() {
List<PersonBean> list = new ArrayList<PersonBean>();
for (int x = 0; x < 10; x++) {
PersonBean bean = new PersonBean();
bean.setId(x);
bean.setName("Rob Harrop");
bean.setStreet("foo");
list.add(bean);
}
return list;
}
private static class SimpleProgressMonitor implements JRExportProgressMonitor {
private boolean invoked = false;
@Override
public void afterPageExport() {
this.invoked = true;
}
public boolean isInvoked() {
return invoked;
}
}
}
@@ -1,64 +0,0 @@
/*
* Copyright 2002-2005 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ui.jasperreports;
/**
* @author Rob Harrop
*/
public class PersonBean {
private int id;
private String name;
private String street;
private String city;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
}
@@ -1,64 +0,0 @@
/*
* Copyright 2002-2005 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ui.jasperreports;
/**
* @author Rob Harrop
*/
public class ProductBean {
private int id;
private String name;
private float quantity;
private float price;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getQuantity() {
return quantity;
}
public void setQuantity(float quantity) {
this.quantity = quantity;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,7 @@
package org.springframework.cache;
/**
* Interface that defines the common cache operations.
* Interface that defines common cache operations.
*
* <b>Note:</b> Due to the generic use of caching, it is recommended that
* implementations allow storage of <tt>null</tt> values (for example to
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
package org.springframework.cache.annotation;
import java.util.Collection;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
@@ -27,12 +26,11 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportAware;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
/**
* Abstract base {@code @Configuration} class providing common structure for enabling
* Spring's annotation-driven cache management capability.
* Abstract base {@code @Configuration} class providing common structure
* for enabling Spring's annotation-driven cache management capability.
*
* @author Chris Beams
* @since 3.1
@@ -42,22 +40,28 @@ import org.springframework.util.CollectionUtils;
public abstract class AbstractCachingConfiguration implements ImportAware {
protected AnnotationAttributes enableCaching;
protected CacheManager cacheManager;
protected KeyGenerator keyGenerator;
@Autowired(required=false)
@Autowired(required = false)
private Collection<CacheManager> cacheManagerBeans;
@Autowired(required=false)
@Autowired(required = false)
private Collection<CachingConfigurer> cachingConfigurers;
public void setImportMetadata(AnnotationMetadata importMetadata) {
this.enableCaching = AnnotationAttributes.fromMap(
importMetadata.getAnnotationAttributes(EnableCaching.class.getName(), false));
Assert.notNull(this.enableCaching,
"@EnableCaching is not present on importing class " +
importMetadata.getClassName());
if (this.enableCaching == null) {
throw new IllegalArgumentException(
"@EnableCaching is not present on importing class " + importMetadata.getClassName());
}
}
/**
* Determine which {@code CacheManager} bean to use. Prefer the result of
* {@link CachingConfigurer#cacheManager()} over any by-type matching. If none, fall
@@ -68,20 +72,20 @@ public abstract class AbstractCachingConfiguration implements ImportAware {
*/
@PostConstruct
protected void reconcileCacheManager() {
if (!CollectionUtils.isEmpty(cachingConfigurers)) {
int nConfigurers = cachingConfigurers.size();
if (!CollectionUtils.isEmpty(this.cachingConfigurers)) {
int nConfigurers = this.cachingConfigurers.size();
if (nConfigurers > 1) {
throw new IllegalStateException(nConfigurers + " implementations of " +
"CachingConfigurer were found when only 1 was expected. " +
"Refactor the configuration such that CachingConfigurer is " +
"implemented only once or not at all.");
}
CachingConfigurer cachingConfigurer = cachingConfigurers.iterator().next();
CachingConfigurer cachingConfigurer = this.cachingConfigurers.iterator().next();
this.cacheManager = cachingConfigurer.cacheManager();
this.keyGenerator = cachingConfigurer.keyGenerator();
}
else if (!CollectionUtils.isEmpty(cacheManagerBeans)) {
int nManagers = cacheManagerBeans.size();
else if (!CollectionUtils.isEmpty(this.cacheManagerBeans)) {
int nManagers = this.cacheManagerBeans.size();
if (nManagers > 1) {
throw new IllegalStateException(nManagers + " beans of type CacheManager " +
"were found when only 1 was expected. Remove all but one of the " +
@@ -89,8 +93,7 @@ public abstract class AbstractCachingConfiguration implements ImportAware {
"to make explicit which CacheManager should be used for " +
"annotation-driven cache management.");
}
CacheManager cacheManager = cacheManagerBeans.iterator().next();
this.cacheManager = cacheManager;
this.cacheManager = cacheManager = this.cacheManagerBeans.iterator().next();
// keyGenerator remains null; will fall back to default within CacheInterceptor
}
else {
@@ -99,4 +102,5 @@ public abstract class AbstractCachingConfiguration implements ImportAware {
"from your configuration.");
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -151,13 +151,12 @@ public @interface EnableCaching {
* Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
* to standard Java interface-based proxies. The default is {@code false}. <strong>
* Applicable only if {@link #mode()} is set to {@link AdviceMode#PROXY}</strong>.
*
* <p>Note that setting this attribute to {@code true} will affect <em>all</em>
* Spring-managed beans requiring proxying, not just those marked with
* {@code @Cacheable}. For example, other beans marked with Spring's
* {@code @Transactional} annotation will be upgraded to subclass proxying at the same
* time. This approach has no negative impact in practice unless one is explicitly
* expecting one type of proxy vs another, e.g. in tests.
* Spring-managed beans requiring proxying, not just those marked with {@code @Cacheable}.
* For example, other beans marked with Spring's {@code @Transactional} annotation will
* be upgraded to subclass proxying at the same time. This approach has no negative
* impact in practice unless one is explicitly expecting one type of proxy vs another,
* e.g. in tests.
*/
boolean proxyTargetClass() default false;
@@ -174,4 +173,5 @@ public @interface EnableCaching {
* The default is {@link Ordered#LOWEST_PRECEDENCE}.
*/
int order() default Ordered.LOWEST_PRECEDENCE;
}
@@ -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.
@@ -70,7 +70,10 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
if (cachings != null) {
ops = lazyInit(ops);
for (Caching caching : cachings) {
ops.addAll(parseCachingAnnotation(ae, caching));
Collection<CacheOperation> cachingOps = parseCachingAnnotation(ae, caching);
if (cachingOps != null) {
ops.addAll(cachingOps);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,16 +16,17 @@
package org.springframework.cache.concurrent;
import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;
import java.io.Serializable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;
import org.springframework.util.Assert;
/**
* Simple {@link Cache} implementation based on the core JDK
* {@code java.util.concurrent} package.
* Simple {@link org.springframework.cache.Cache} implementation based on the
* core JDK {@code java.util.concurrent} package.
*
* <p>Useful for testing or simple caching scenarios, typically in combination
* with {@link org.springframework.cache.support.SimpleCacheManager} or
@@ -62,7 +63,8 @@ public class ConcurrentMapCache implements Cache {
/**
* Create a new ConcurrentMapCache with the specified name.
* @param name the name of the cache
* @param allowNullValues whether to accept and convert null values for this cache
* @param allowNullValues whether to accept and convert {@code null}
* values for this cache
*/
public ConcurrentMapCache(String name, boolean allowNullValues) {
this(name, new ConcurrentHashMap<Object, Object>(256), allowNullValues);
@@ -70,13 +72,15 @@ public class ConcurrentMapCache implements Cache {
/**
* Create a new ConcurrentMapCache with the specified name and the
* given internal ConcurrentMap to use.
* given internal {@link ConcurrentMap} to use.
* @param name the name of the cache
* @param store the ConcurrentMap to use as an internal store
* @param allowNullValues whether to allow {@code null} values
* (adapting them to an internal null holder value)
*/
public ConcurrentMapCache(String name, ConcurrentMap<Object, Object> store, boolean allowNullValues) {
Assert.notNull(name, "Name must not be null");
Assert.notNull(store, "Store must not be null");
this.name = name;
this.store = store;
this.allowNullValues = allowNullValues;
@@ -142,6 +146,10 @@ public class ConcurrentMapCache implements Cache {
@SuppressWarnings("serial")
private static class NullHolder implements Serializable {
private Object readResolve() {
return NULL_HOLDER;
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -212,13 +212,14 @@ public abstract class AbstractFallbackCacheOperationSource implements CacheOpera
return false;
}
DefaultCacheKey otherKey = (DefaultCacheKey) other;
return (this.method.equals(otherKey.method) && ObjectUtils.nullSafeEquals(this.targetClass,
otherKey.targetClass));
return (this.method.equals(otherKey.method) &&
ObjectUtils.nullSafeEquals(this.targetClass, otherKey.targetClass));
}
@Override
public int hashCode() {
return this.method.hashCode() * 29 + (this.targetClass != null ? this.targetClass.hashCode() : 0);
return this.method.hashCode() + (this.targetClass != null ? this.targetClass.hashCode() * 29 : 0);
}
}
}
@@ -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.
@@ -53,6 +53,7 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life
* Name of the ConversionService bean in the factory.
* If none is supplied, default conversion rules apply.
* @see org.springframework.core.convert.ConversionService
* @since 3.0
*/
String CONVERSION_SERVICE_BEAN_NAME = "conversionService";
@@ -60,12 +61,14 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life
* Name of the LoadTimeWeaver bean in the factory. If such a bean is supplied,
* the context will use a temporary ClassLoader for type matching, in order
* to allow the LoadTimeWeaver to process all actual bean classes.
* @since 2.5
* @see org.springframework.instrument.classloading.LoadTimeWeaver
*/
String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";
/**
* Name of the {@link Environment} bean in the factory.
* @since 3.1
*/
String ENVIRONMENT_BEAN_NAME = "environment";
@@ -84,6 +87,7 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life
/**
* Set the unique id of this application context.
* @since 3.0
*/
void setId(String id);
@@ -99,12 +103,14 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life
/**
* Return the Environment for this application context in configurable form.
* @since 3.1
*/
ConfigurableEnvironment getEnvironment();
/**
* Set the {@code Environment} for this application context.
* @param environment the new environment
* @since 3.1
*/
void setEnvironment(ConfigurableEnvironment environment);
@@ -112,9 +118,9 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life
* Add a new BeanFactoryPostProcessor that will get applied to the internal
* bean factory of this application context on refresh, before any of the
* bean definitions get evaluated. To be invoked during context configuration.
* @param beanFactoryPostProcessor the factory processor to register
* @param postProcessor the factory processor to register
*/
void addBeanFactoryPostProcessor(BeanFactoryPostProcessor beanFactoryPostProcessor);
void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor);
/**
* Add a new ApplicationListener that will be notified on context events
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,13 +17,15 @@
package org.springframework.context;
/**
* Interface defining methods for start/stop lifecycle control.
* A common interface defining methods for start/stop lifecycle control.
* The typical use case for this is to control asynchronous processing.
* <b>NOTE: This interface does not imply specific auto-startup semantics.
* Consider implementing {@link SmartLifecycle} for that purpose.</b>
*
* <p>Can be implemented by both components (typically a Spring bean defined in
* a Spring {@link org.springframework.beans.factory.BeanFactory}) and containers
* (typically a Spring {@link ApplicationContext}). Containers will propagate
* start/stop signals to all components that apply.
* <p>Can be implemented by both components (typically a Spring bean defined in a
* Spring context) and containers (typically a Spring {@link ApplicationContext}
* itself). Containers will propagate start/stop signals to all components that
* apply within each container, e.g. for a stop/restart scenario at runtime.
*
* <p>Can be used for direct invocations or for management operations via JMX.
* In the latter case, the {@link org.springframework.jmx.export.MBeanExporter}
@@ -32,10 +34,10 @@ package org.springframework.context;
* restricting the visibility of activity-controlled components to the Lifecycle
* interface.
*
* <p>Note that the Lifecycle interface is only supported on <b>top-level singleton beans</b>.
* On any other component, the Lifecycle interface will remain undetected and hence ignored.
* Also, note that the extended {@link SmartLifecycle} interface provides more sophisticated
* integration with the container's startup and shutdown phases.
* <p>Note that the Lifecycle interface is only supported on <b>top-level singleton
* beans</b>. On any other component, the Lifecycle interface will remain undetected
* and hence ignored. Also, note that the extended {@link SmartLifecycle} interface
* provides integration with the application context's startup and shutdown phases.
*
* @author Juergen Hoeller
* @since 2.0
@@ -51,6 +53,7 @@ public interface Lifecycle {
* Should not throw an exception if the component is already running.
* <p>In the case of a container, this will propagate the start signal
* to all components that apply.
* @see SmartLifecycle#isAutoStartup()
*/
void start();
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,8 +17,8 @@
package org.springframework.context;
/**
* An extension of the {@link Lifecycle} interface for those objects that require to be
* started upon ApplicationContext refresh and/or shutdown in a particular order.
* An extension of the {@link Lifecycle} interface for those objects that require to
* be started upon ApplicationContext refresh and/or shutdown in a particular order.
* The {@link #isAutoStartup()} return value indicates whether this object should
* be started at the time of a context refresh. The callback-accepting
* {@link #stop(Runnable)} method is useful for objects that have an asynchronous
@@ -55,26 +55,37 @@ package org.springframework.context;
*
* @author Mark Fisher
* @since 3.0
* @see LifecycleProcessor
* @see ConfigurableApplicationContext
*/
public interface SmartLifecycle extends Lifecycle, Phased {
/**
* Return whether this Lifecycle component should be started automatically
* by the container when the ApplicationContext is refreshed. A value of
* "false" indicates that the component is intended to be started manually.
* Returns {@code true} if this {@code Lifecycle} component should get
* started automatically by the container at the time that the containing
* {@link ApplicationContext} gets refreshed.
* <p>A value of {@code false} indicates that the component is intended to
* be started through an explicit {@link #start()} call instead, analogous
* to a plain {@link Lifecycle} implementation.
* @see #start()
* @see #getPhase()
* @see LifecycleProcessor#onRefresh()
* @see ConfigurableApplicationContext#refresh()
*/
boolean isAutoStartup();
/**
* Indicates that a Lifecycle component must stop if it is currently running.
* <p>The provided callback is used by the {@link LifecycleProcessor} to support an
* ordered, and potentially concurrent, shutdown of all components having a
* <p>The provided callback is used by the {@link LifecycleProcessor} to support
* an ordered, and potentially concurrent, shutdown of all components having a
* common shutdown order value. The callback <b>must</b> be executed after
* the SmartLifecycle component does indeed stop.
* <p>The {@code LifecycleProcessor} will call <i>only</i> this variant of the
* the {@code SmartLifecycle} component does indeed stop.
* <p>The {@link LifecycleProcessor} will call <i>only</i> this variant of the
* {@code stop} method; i.e. {@link Lifecycle#stop()} will not be called for
* {@link SmartLifecycle} implementations unless explicitly delegated to within
* this method.
* {@code SmartLifecycle} implementations unless explicitly delegated to within
* the implementation of this method.
* @see #stop()
* @see #getPhase()
*/
void stop(Runnable callback);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -139,7 +139,7 @@ public class AnnotationBeanNameGenerator implements BeanNameGenerator {
* <p>The default implementation simply builds a decapitalized version
* of the short class name: e.g. "mypackage.MyJdbcDao" -> "myJdbcDao".
* <p>Note that inner classes will thus have names of the form
* "outerClassName.innerClassName", which because of the period in the
* "outerClassName.InnerClassName", which because of the period in the
* name may be an issue if you are autowiring by name.
* @param definition the bean definition to build a bean name for
* @return the default bean name (never {@code null})
@@ -78,7 +78,7 @@ public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
logger.warn(String.format("%s was imported but no annotations were found " +
"having both 'mode' and 'proxyTargetClass' attributes of type " +
"AdviceMode and boolean respectively. This means that auto proxy " +
"creator registration and configuration may not have occured as " +
"creator registration and configuration may not have occurred as " +
"intended, and components may not be proxied as expected. Check to " +
"ensure that %s has been @Import'ed on the same class where these " +
"annotations are declared; otherwise remove the import of %s " +
@@ -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.
@@ -39,7 +39,8 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
* public MyBean myBean() {
* // instantiate and configure MyBean obj
* return obj;
* }</pre>
* }
* </pre>
*
* <h3>Bean Names</h3>
*
@@ -55,7 +56,8 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
* public MyBean myBean() {
* // instantiate and configure MyBean obj
* return obj;
* }</pre>
* }
* </pre>
*
* <h3>Scope, DependsOn, Primary, and Lazy</h3>
*
@@ -70,7 +72,8 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
* public MyBean myBean() {
* // instantiate and configure MyBean obj
* return obj;
* }</pre>
* }
* </pre>
*
* <h3>{@code @Bean} Methods in {@code @Configuration} Classes</h3>
*
@@ -87,14 +90,17 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
* <pre class="code">
* &#064;Configuration
* public class AppConfig {
*
* &#064;Bean
* public FooService fooService() {
* return new FooService(fooRepository());
* }
*
* &#064;Bean
* public FooRepository fooRepository() {
* return new JdbcFooRepository(dataSource());
* }
*
* // ...
* }</pre>
*
@@ -152,7 +158,8 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
* &#064;Bean
* public static PropertyPlaceholderConfigurer ppc() {
* // instantiate, configure and return ppc ...
* }</pre>
* }
* </pre>
*
* By marking this method as {@code static}, it can be invoked without causing instantiation of its
* declaring {@code @Configuration} class, thus avoiding the above-mentioned lifecycle conflicts.
@@ -191,6 +198,13 @@ public @interface Bean {
/**
* Are dependencies to be injected via convention-based autowiring by name or type?
* <p>Note that this autowire mode is just about externally driven autowiring based
* on bean property setter methods by convention, analogous to XML bean definitions.
* <p>The default mode does allow for annotation-driven autowiring. "no" refers to
* externally driven autowiring only, not affecting any autowiring demands that the
* bean class itself expresses through annotations.
* @see Autowire#BY_NAME
* @see Autowire#BY_TYPE
*/
Autowire autowire() default Autowire.NO;
@@ -283,7 +283,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
if (beanType != null) {
InjectionMetadata metadata = findResourceMetadata(beanName, beanType);
InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
}
@@ -299,7 +299,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass());
InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
try {
metadata.inject(bean, beanName, pvs);
}
@@ -310,15 +310,19 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
}
private InjectionMetadata findResourceMetadata(String beanName, final Class<?> clazz) {
// Quick check on the concurrent map first, with minimal locking.
private InjectionMetadata findResourceMetadata(String beanName, final Class<?> clazz, PropertyValues pvs) {
// Fall back to class name as cache key, for backwards compatibility with custom callers.
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// Quick check on the concurrent map first, with minimal locking.
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
Class<?> targetClass = clazz;
@@ -357,7 +361,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
if (method.getParameterTypes().length != 1) {
throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method);
}
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method, clazz);
currElements.add(new WebServiceRefElement(method, pd));
}
else if (ejbRefClass != null && method.isAnnotationPresent(ejbRefClass)) {
@@ -367,7 +371,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
if (method.getParameterTypes().length != 1) {
throw new IllegalStateException("@EJB annotation requires a single-arg method: " + method);
}
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method, clazz);
currElements.add(new EjbRefElement(method, pd));
}
else if (method.isAnnotationPresent(Resource.class)) {
@@ -379,7 +383,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
throw new IllegalStateException("@Resource annotation requires a single-arg method: " + method);
}
if (!ignoredResourceTypes.contains(paramTypes[0].getName())) {
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method, clazz);
currElements.add(new ResourceElement(method, pd));
}
}
@@ -240,9 +240,8 @@ class ConfigurationClassEnhancer {
/**
* Enhance a {@link Bean @Bean} method to check the supplied BeanFactory for the
* existence of this bean object.
* @throws Throwable as a catch-all for any exception that may be thrown when
* invoking the super implementation of the proxied method i.e., the actual
* {@code @Bean} method.
* @throws Throwable as a catch-all for any exception that may be thrown when invoking the
* super implementation of the proxied method i.e., the actual {@code @Bean} method
*/
public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,
MethodProxy cglibMethodProxy) throws Throwable {
@@ -23,7 +23,6 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
@@ -101,8 +100,6 @@ class ConfigurationClassParser {
private final ImportStack importStack = new ImportStack();
private final Set<Class<?>> importBeanDefinitionRegistrars = new HashSet<Class<?>>();
/**
* Create a new {@link ConfigurationClassParser} instance that will be used
@@ -202,7 +199,7 @@ class ConfigurationClassParser {
// Process any @Import annotations
Set<Object> imports = new LinkedHashSet<Object>();
Set<Object> visited = new LinkedHashSet<Object>();
Set<String> visited = new LinkedHashSet<String>();
collectImports(metadata, imports, visited);
if (!imports.isEmpty()) {
processImport(configClass, metadata, imports, true);
@@ -318,7 +315,7 @@ class ConfigurationClassParser {
* @param visited used to track visited classes to prevent infinite recursion
* @throws IOException if there is any problem reading metadata from the named class
*/
private void collectImports(AnnotationMetadata metadata, Set<Object> imports, Set<Object> visited) throws IOException {
private void collectImports(AnnotationMetadata metadata, Set<Object> imports, Set<String> visited) throws IOException {
String className = metadata.getClassName();
if (visited.add(className)) {
if (metadata instanceof StandardAnnotationMetadata) {
@@ -330,9 +327,13 @@ class ConfigurationClassParser {
}
Map<String, Object> attributes = stdMetadata.getAnnotationAttributes(Import.class.getName(), false);
if (attributes != null) {
Class[] value = (Class[]) attributes.get("value");
Class<?>[] value = (Class<?>[]) attributes.get("value");
if (!ObjectUtils.isEmpty(value)) {
imports.addAll(Arrays.asList(value));
for (Class<?> importedClass : value) {
// Catch duplicate from ASM-based parsing...
imports.remove(importedClass.getName());
imports.add(importedClass);
}
}
}
}
@@ -345,7 +346,7 @@ class ConfigurationClassParser {
imports, visited);
}
catch (ClassNotFoundException ex) {
//
// Silently ignore...
}
}
}
@@ -353,7 +354,19 @@ class ConfigurationClassParser {
if (attributes != null) {
String[] value = (String[]) attributes.get("value");
if (!ObjectUtils.isEmpty(value)) {
imports.addAll(Arrays.asList(value));
for (String importedClassName : value) {
// Catch duplicate from reflection-based parsing...
boolean alreadyThereAsClass = false;
for (Object existingImport : imports) {
if (existingImport instanceof Class &&
((Class<?>) existingImport).getName().equals(importedClassName)) {
alreadyThereAsClass = true;
}
}
if (!alreadyThereAsClass) {
imports.add(importedClassName);
}
}
}
}
}
@@ -384,13 +397,10 @@ class ConfigurationClassParser {
// delegate to it to register additional bean definitions
Class<?> candidateClass = (candidate instanceof Class ? (Class) candidate :
this.resourceLoader.getClassLoader().loadClass((String) candidate));
if (!this.importBeanDefinitionRegistrars.contains(candidateClass)) {
ImportBeanDefinitionRegistrar registrar =
BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
invokeAwareMethods(registrar);
registrar.registerBeanDefinitions(metadata, this.registry);
this.importBeanDefinitionRegistrars.add(candidateClass);
}
ImportBeanDefinitionRegistrar registrar =
BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
invokeAwareMethods(registrar);
registrar.registerBeanDefinitions(metadata, this.registry);
}
else {
// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,16 +26,15 @@ import org.springframework.context.weaving.DefaultContextLoadTimeWeaver;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.instrument.classloading.LoadTimeWeaver;
import org.springframework.util.Assert;
import static org.springframework.context.weaving.AspectJWeavingEnabler.*;
/**
* {@code @Configuration} class that registers a {@link LoadTimeWeaver} bean.
*
* <p>This configuration class is automatically imported when using the @{@link
* EnableLoadTimeWeaving} annotation. See {@code @EnableLoadTimeWeaving} Javadoc for
* complete usage details.
* <p>This configuration class is automatically imported when using the
* {@link EnableLoadTimeWeaving} annotation. See {@code @EnableLoadTimeWeaving}
* javadoc for complete usage details.
*
* @author Chris Beams
* @since 3.1
@@ -47,28 +46,31 @@ public class LoadTimeWeavingConfiguration implements ImportAware, BeanClassLoade
private AnnotationAttributes enableLTW;
@Autowired(required=false)
@Autowired(required = false)
private LoadTimeWeavingConfigurer ltwConfigurer;
private ClassLoader beanClassLoader;
public void setImportMetadata(AnnotationMetadata importMetadata) {
this.enableLTW = MetadataUtils.attributesFor(importMetadata, EnableLoadTimeWeaving.class);
Assert.notNull(this.enableLTW,
"@EnableLoadTimeWeaving is not present on importing class " +
importMetadata.getClassName());
if (this.enableLTW == null) {
throw new IllegalArgumentException(
"@EnableLoadTimeWeaving is not present on importing class " + importMetadata.getClassName());
}
}
public void setBeanClassLoader(ClassLoader beanClassLoader) {
this.beanClassLoader = beanClassLoader;
}
@Bean(name=ConfigurableApplicationContext.LOAD_TIME_WEAVER_BEAN_NAME)
@Bean(name = ConfigurableApplicationContext.LOAD_TIME_WEAVER_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public LoadTimeWeaver loadTimeWeaver() {
LoadTimeWeaver loadTimeWeaver = null;
if (ltwConfigurer != null) {
if (this.ltwConfigurer != null) {
// the user has provided a custom LTW instance
loadTimeWeaver = ltwConfigurer.getLoadTimeWeaver();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,7 +30,6 @@ import org.springframework.jmx.export.annotation.AnnotationMBeanExporter;
import org.springframework.jmx.support.RegistrationPolicy;
import org.springframework.jmx.support.WebSphereMBeanServerFactoryBean;
import org.springframework.jndi.JndiLocatorDelegate;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
@@ -50,23 +49,26 @@ public class MBeanExportConfiguration implements ImportAware, BeanFactoryAware {
private static final String MBEAN_EXPORTER_BEAN_NAME = "mbeanExporter";
private AnnotationAttributes attributes;
private AnnotationAttributes enableMBeanExport;
private BeanFactory beanFactory;
public void setImportMetadata(AnnotationMetadata importMetadata) {
Map<String, Object> map = importMetadata.getAnnotationAttributes(EnableMBeanExport.class.getName());
this.attributes = AnnotationAttributes.fromMap(map);
Assert.notNull(this.attributes,
"@EnableMBeanExport is not present on importing class " + importMetadata.getClassName());
this.enableMBeanExport = AnnotationAttributes.fromMap(map);
if (this.enableMBeanExport == null) {
throw new IllegalArgumentException(
"@EnableMBeanExport is not present on importing class " + importMetadata.getClassName());
}
}
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Bean(name=MBEAN_EXPORTER_BEAN_NAME)
@Bean(name = MBEAN_EXPORTER_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public AnnotationMBeanExporter mbeanExporter() {
AnnotationMBeanExporter exporter = new AnnotationMBeanExporter();
@@ -77,14 +79,14 @@ public class MBeanExportConfiguration implements ImportAware, BeanFactoryAware {
}
private void setupDomain(AnnotationMBeanExporter exporter) {
String defaultDomain = this.attributes.getString("defaultDomain");
String defaultDomain = this.enableMBeanExport.getString("defaultDomain");
if (StringUtils.hasText(defaultDomain)) {
exporter.setDefaultDomain(defaultDomain);
}
}
private void setupServer(AnnotationMBeanExporter exporter) {
String server = this.attributes.getString("server");
String server = this.enableMBeanExport.getString("server");
if (StringUtils.hasText(server)) {
exporter.setServer(this.beanFactory.getBean(server, MBeanServer.class));
}
@@ -97,7 +99,7 @@ public class MBeanExportConfiguration implements ImportAware, BeanFactoryAware {
}
private void setupRegistrationPolicy(AnnotationMBeanExporter exporter) {
RegistrationPolicy registrationPolicy = this.attributes.getEnum("registration");
RegistrationPolicy registrationPolicy = this.enableMBeanExport.getEnum("registration");
exporter.setRegistrationPolicy(registrationPolicy);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,16 +28,16 @@ import org.springframework.beans.factory.config.BeanDefinition;
* Indicates the 'role' hint for a given bean.
*
* <p>May be used on any class directly or indirectly annotated with
* {@link org.springframework.stereotype.Component} or on methods annotated with
* {@link Bean}.
* {@link org.springframework.stereotype.Component} or on methods
* annotated with {@link Bean}.
*
* <p>If this annotation is not present on a Component or Bean definition, the
* default value of {@link BeanDefinition#ROLE_APPLICATION} will apply.
* <p>If this annotation is not present on a Component or Bean definition,
* the default value of {@link BeanDefinition#ROLE_APPLICATION} will apply.
*
* <p>If Role is present on a {@link Configuration @Configuration} class, this
* indicates the role of the configuration class bean definition and does not
* cascade to all @{@code Bean} methods defined within. This behavior is
* different than that of the @{@link Lazy} annotation, for example.
* <p>If Role is present on a {@link Configuration @Configuration} class,
* this indicates the role of the configuration class bean definition and
* does not cascade to all @{@code Bean} methods defined within. This behavior
* is different than that of the @{@link Lazy} annotation, for example.
*
* @author Chris Beams
* @since 3.1
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@ import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanFactory;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.OrderComparator;
@@ -64,42 +65,8 @@ public abstract class AbstractApplicationEventMulticaster
private BeanFactory beanFactory;
private Object retrievalMutex = this.defaultRetriever;
public void addApplicationListener(ApplicationListener listener) {
synchronized (this.defaultRetriever) {
this.defaultRetriever.applicationListeners.add(listener);
this.retrieverCache.clear();
}
}
public void addApplicationListenerBean(String listenerBeanName) {
synchronized (this.defaultRetriever) {
this.defaultRetriever.applicationListenerBeans.add(listenerBeanName);
this.retrieverCache.clear();
}
}
public void removeApplicationListener(ApplicationListener listener) {
synchronized (this.defaultRetriever) {
this.defaultRetriever.applicationListeners.remove(listener);
this.retrieverCache.clear();
}
}
public void removeApplicationListenerBean(String listenerBeanName) {
synchronized (this.defaultRetriever) {
this.defaultRetriever.applicationListenerBeans.remove(listenerBeanName);
this.retrieverCache.clear();
}
}
public void removeAllListeners() {
synchronized (this.defaultRetriever) {
this.defaultRetriever.applicationListeners.clear();
this.defaultRetriever.applicationListenerBeans.clear();
this.retrieverCache.clear();
}
}
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
@@ -110,6 +77,9 @@ public abstract class AbstractApplicationEventMulticaster
if (this.beanClassLoader == null && beanFactory instanceof ConfigurableBeanFactory) {
this.beanClassLoader = ((ConfigurableBeanFactory) beanFactory).getBeanClassLoader();
}
if (beanFactory instanceof AbstractBeanFactory) {
this.retrievalMutex = ((AbstractBeanFactory) beanFactory).getSingletonMutex();
}
}
private BeanFactory getBeanFactory() {
@@ -121,13 +91,50 @@ public abstract class AbstractApplicationEventMulticaster
}
public void addApplicationListener(ApplicationListener listener) {
synchronized (this.retrievalMutex) {
this.defaultRetriever.applicationListeners.add(listener);
this.retrieverCache.clear();
}
}
public void addApplicationListenerBean(String listenerBeanName) {
synchronized (this.retrievalMutex) {
this.defaultRetriever.applicationListenerBeans.add(listenerBeanName);
this.retrieverCache.clear();
}
}
public void removeApplicationListener(ApplicationListener listener) {
synchronized (this.retrievalMutex) {
this.defaultRetriever.applicationListeners.remove(listener);
this.retrieverCache.clear();
}
}
public void removeApplicationListenerBean(String listenerBeanName) {
synchronized (this.retrievalMutex) {
this.defaultRetriever.applicationListenerBeans.remove(listenerBeanName);
this.retrieverCache.clear();
}
}
public void removeAllListeners() {
synchronized (this.retrievalMutex) {
this.defaultRetriever.applicationListeners.clear();
this.defaultRetriever.applicationListenerBeans.clear();
this.retrieverCache.clear();
}
}
/**
* Return a Collection containing all ApplicationListeners.
* @return a Collection of ApplicationListeners
* @see org.springframework.context.ApplicationListener
*/
protected Collection<ApplicationListener> getApplicationListeners() {
synchronized (this.defaultRetriever) {
synchronized (this.retrievalMutex) {
return this.defaultRetriever.getApplicationListeners();
}
}
@@ -145,43 +152,74 @@ public abstract class AbstractApplicationEventMulticaster
Object source = event.getSource();
Class<?> sourceType = (source != null ? source.getClass() : null);
ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);
// Quick check for existing entry on ConcurrentHashMap...
ListenerRetriever retriever = this.retrieverCache.get(cacheKey);
if (retriever != null) {
return retriever.getApplicationListeners();
}
else {
retriever = new ListenerRetriever(true);
LinkedList<ApplicationListener> allListeners = new LinkedList<ApplicationListener>();
Set<ApplicationListener> listeners;
Set<String> listenerBeans;
synchronized (this.defaultRetriever) {
listeners = new LinkedHashSet<ApplicationListener>(this.defaultRetriever.applicationListeners);
listenerBeans = new LinkedHashSet<String>(this.defaultRetriever.applicationListenerBeans);
if (this.beanClassLoader == null ||
(ClassUtils.isCacheSafe(eventType, this.beanClassLoader) &&
(sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
// Fully synchronized building and caching of a ListenerRetriever
synchronized (this.retrievalMutex) {
retriever = this.retrieverCache.get(cacheKey);
if (retriever != null) {
return retriever.getApplicationListeners();
}
retriever = new ListenerRetriever(true);
Collection<ApplicationListener> listeners =
retrieveApplicationListeners(eventType, sourceType, retriever);
this.retrieverCache.put(cacheKey, retriever);
return listeners;
}
for (ApplicationListener listener : listeners) {
if (supportsEvent(listener, eventType, sourceType)) {
}
else {
// No ListenerRetriever caching -> no synchronization necessary
return retrieveApplicationListeners(eventType, sourceType, null);
}
}
/**
* Actually retrieve the application listeners for the given event and source type.
* @param eventType the application event type
* @param sourceType the event source type
* @param retriever the ListenerRetriever, if supposed to populate one (for caching purposes)
* @return the pre-filtered list of application listeners for the given event and source type
*/
private Collection<ApplicationListener> retrieveApplicationListeners(
Class<? extends ApplicationEvent> eventType, Class<?> sourceType, ListenerRetriever retriever) {
LinkedList<ApplicationListener> allListeners = new LinkedList<ApplicationListener>();
Set<ApplicationListener> listeners;
Set<String> listenerBeans;
synchronized (this.retrievalMutex) {
listeners = new LinkedHashSet<ApplicationListener>(this.defaultRetriever.applicationListeners);
listenerBeans = new LinkedHashSet<String>(this.defaultRetriever.applicationListenerBeans);
}
for (ApplicationListener listener : listeners) {
if (supportsEvent(listener, eventType, sourceType)) {
if (retriever != null) {
retriever.applicationListeners.add(listener);
}
allListeners.add(listener);
}
}
if (!listenerBeans.isEmpty()) {
BeanFactory beanFactory = getBeanFactory();
for (String listenerBeanName : listenerBeans) {
ApplicationListener listener = beanFactory.getBean(listenerBeanName, ApplicationListener.class);
if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
if (retriever != null) {
retriever.applicationListenerBeans.add(listenerBeanName);
}
allListeners.add(listener);
}
}
if (!listenerBeans.isEmpty()) {
BeanFactory beanFactory = getBeanFactory();
for (String listenerBeanName : listenerBeans) {
ApplicationListener listener = beanFactory.getBean(listenerBeanName, ApplicationListener.class);
if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
retriever.applicationListenerBeans.add(listenerBeanName);
allListeners.add(listener);
}
}
}
OrderComparator.sort(allListeners);
if (this.beanClassLoader == null ||
(ClassUtils.isCacheSafe(eventType, this.beanClassLoader) &&
(sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
this.retrieverCache.put(cacheKey, retriever);
}
return allListeners;
}
OrderComparator.sort(allListeners);
return allListeners;
}
/**
@@ -197,7 +235,7 @@ public abstract class AbstractApplicationEventMulticaster
* for the given event type
*/
protected boolean supportsEvent(
ApplicationListener listener, Class<? extends ApplicationEvent> eventType, Class sourceType) {
ApplicationListener listener, Class<? extends ApplicationEvent> eventType, Class<?> sourceType) {
SmartApplicationListener smartListener = (listener instanceof SmartApplicationListener ?
(SmartApplicationListener) listener : new GenericApplicationListenerAdapter(listener));
@@ -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.
@@ -53,6 +53,7 @@ import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.HierarchicalMessageSource;
import org.springframework.context.LifecycleProcessor;
@@ -404,8 +405,9 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
}
}
public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor beanFactoryPostProcessor) {
this.beanFactoryPostProcessors.add(beanFactoryPostProcessor);
public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
this.beanFactoryPostProcessors.add(postProcessor);
}
@@ -418,6 +420,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
}
public void addApplicationListener(ApplicationListener<?> listener) {
Assert.notNull(listener, "ApplicationListener must not be null");
if (this.applicationEventMulticaster != null) {
this.applicationEventMulticaster.addApplicationListener(listener);
}
@@ -483,7 +486,10 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
}
catch (BeansException ex) {
logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex);
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
@@ -557,11 +563,12 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
// Configure the bean factory with context callbacks.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
@@ -884,11 +891,12 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String lisName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(lisName);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
}
@@ -1287,7 +1295,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
}
public boolean isRunning() {
return getLifecycleProcessor().isRunning();
return (this.lifecycleProcessor != null && this.lifecycleProcessor.isRunning());
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -422,6 +422,8 @@ public class ResourceBundleMessageSource extends AbstractMessageSource implement
@Override
public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException, IOException {
// Special handling of default encoding
if (format.equals("java.properties")) {
String bundleName = toBundleName(baseName, locale);
final String resourceName = toResourceName(bundleName, "properties");
@@ -468,6 +470,7 @@ public class ResourceBundleMessageSource extends AbstractMessageSource implement
}
}
else {
// Delegate handling of "java.class" format to standard Control
return super.newBundle(baseName, locale, format, loader, reload);
}
}
@@ -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,7 @@
package org.springframework.format.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -28,19 +29,19 @@ import java.lang.annotation.Target;
* Can be applied to {@code java.util.Date}, {@code java.util.Calendar}, {@code java.long.Long},
* Joda-Time value types; and as of Spring 4 and JDK 8, to JSR-310 <code>java.time</code> types too.
*
* <p>For style-based formatting, set the {@link #style()} attribute to be the style pattern code.
* <p>For style-based formatting, set the {@link #style} attribute to be the style pattern code.
* The first character of the code is the date style, and the second character is the time style.
* Specify a character of 'S' for short style, 'M' for medium, 'L' for long, and 'F' for full.
* A date or time may be omitted by specifying the style character '-'.
*
* <p>For ISO-based formatting, set the {@link #iso()} attribute to be the desired {@link ISO} format,
* <p>For ISO-based formatting, set the {@link #iso} attribute to be the desired {@link ISO} format,
* such as {@link ISO#DATE}. For custom formatting, set the {@link #pattern()} attribute to be the
* DateTime pattern, such as {@code yyyy/MM/dd hh:mm:ss a}.
*
* <p>Each attribute is mutually exclusive, so only set one attribute per annotation instance
* (the one most convenient one for your formatting needs).
* When the pattern attribute is specified, it takes precedence over both the style and ISO attribute.
* When the iso attribute is specified, if takes precedence over the style attribute.
* When the {@link #iso} attribute is specified, it takes precedence over the style attribute.
* When no annotation attributes are specified, the default format applied is style-based
* with a style code of 'SS' (short date, short time).
*
@@ -49,8 +50,9 @@ import java.lang.annotation.Target;
* @since 3.0
* @see org.joda.time.format.DateTimeFormat
*/
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
public @interface DateTimeFormat {
/**
@@ -80,23 +82,23 @@ public @interface DateTimeFormat {
/**
* Common ISO date time format patterns.
*/
public enum ISO {
enum ISO {
/**
* The most common ISO Date Format {@code yyyy-MM-dd},
* e.g. 2000-10-31.
* e.g. "2000-10-31".
*/
DATE,
/**
* The most common ISO Time Format {@code HH:mm:ss.SSSZ},
* e.g. 01:30:00.000-05:00.
* e.g. "01:30:00.000-05:00".
*/
TIME,
/**
* The most common ISO DateTime Format {@code yyyy-MM-dd'T'HH:mm:ss.SSSZ},
* e.g. 2000-10-31 01:30:00.000-05:00.
* e.g. "2000-10-31T01:30:00.000-05:00".
* <p>This is the default if no annotation value is specified.
*/
DATE_TIME,
@@ -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.
@@ -189,7 +189,7 @@ public class DateFormatter implements Formatter<Date> {
if (timeStyle != -1) {
return DateFormat.getTimeInstance(timeStyle, locale);
}
throw new IllegalStateException("Unsupported style pattern '"+ this.stylePattern+ "'");
throw new IllegalStateException("Unsupported style pattern '" + this.stylePattern + "'");
}
return DateFormat.getDateInstance(this.style, locale);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -107,7 +107,7 @@ public class MBeanClientInterceptor
private boolean useStrictCasing = true;
private Class managementInterface;
private Class<?> managementInterface;
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
@@ -215,7 +215,7 @@ public class MBeanClientInterceptor
* setters and getters for MBean attributes and conventional Java methods
* for MBean operations.
*/
public void setManagementInterface(Class managementInterface) {
public void setManagementInterface(Class<?> managementInterface) {
this.managementInterface = managementInterface;
}
@@ -223,7 +223,7 @@ public class MBeanClientInterceptor
* Return the management interface of the target MBean,
* or {@code null} if none specified.
*/
protected final Class getManagementInterface() {
protected final Class<?> getManagementInterface() {
return this.managementInterface;
}
@@ -262,7 +262,7 @@ public class MBeanClientInterceptor
this.invocationHandler = null;
if (this.useStrictCasing) {
// Use the JDK's own MBeanServerInvocationHandler,
// in particular for native MXBean support on Java 6.
// in particular for native MXBean support on Java 6+.
if (JmxUtils.isMXBeanSupportAvailable()) {
this.invocationHandler =
new MBeanServerInvocationHandler(this.serverToUse, this.objectName,
@@ -297,7 +297,7 @@ public class MBeanClientInterceptor
MBeanOperationInfo[] operationInfo = info.getOperations();
this.allowedOperations = new HashMap<MethodCacheKey, MBeanOperationInfo>(operationInfo.length);
for (MBeanOperationInfo infoEle : operationInfo) {
Class[] paramTypes = JmxUtils.parameterInfoToTypes(infoEle.getSignature(), this.beanClassLoader);
Class<?>[] paramTypes = JmxUtils.parameterInfoToTypes(infoEle.getSignature(), this.beanClassLoader);
this.allowedOperations.put(new MethodCacheKey(infoEle.getName(), paramTypes), infoEle);
}
}
@@ -531,7 +531,7 @@ public class MBeanClientInterceptor
* is necessary
*/
protected Object convertResultValueIfNecessary(Object result, MethodParameter parameter) {
Class targetClass = parameter.getParameterType();
Class<?> targetClass = parameter.getParameterType();
try {
if (result == null) {
return null;
@@ -549,7 +549,7 @@ public class MBeanClientInterceptor
return convertDataArrayToTargetArray(array, targetClass);
}
else if (Collection.class.isAssignableFrom(targetClass)) {
Class elementType = GenericCollectionTypeResolver.getCollectionParameterType(parameter);
Class<?> elementType = GenericCollectionTypeResolver.getCollectionParameterType(parameter);
if (elementType != null) {
return convertDataArrayToTargetCollection(array, targetClass, elementType);
}
@@ -565,7 +565,7 @@ public class MBeanClientInterceptor
return convertDataArrayToTargetArray(array, targetClass);
}
else if (Collection.class.isAssignableFrom(targetClass)) {
Class elementType = GenericCollectionTypeResolver.getCollectionParameterType(parameter);
Class<?> elementType = GenericCollectionTypeResolver.getCollectionParameterType(parameter);
if (elementType != null) {
return convertDataArrayToTargetCollection(array, targetClass, elementType);
}
@@ -581,8 +581,8 @@ public class MBeanClientInterceptor
}
}
private Object convertDataArrayToTargetArray(Object[] array, Class targetClass) throws NoSuchMethodException {
Class targetType = targetClass.getComponentType();
private Object convertDataArrayToTargetArray(Object[] array, Class<?> targetClass) throws NoSuchMethodException {
Class<?> targetType = targetClass.getComponentType();
Method fromMethod = targetType.getMethod("from", array.getClass().getComponentType());
Object resultArray = Array.newInstance(targetType, array.length);
for (int i = 0; i < array.length; i++) {
@@ -592,11 +592,11 @@ public class MBeanClientInterceptor
}
@SuppressWarnings("unchecked")
private Collection convertDataArrayToTargetCollection(Object[] array, Class collectionType, Class elementType)
private Collection<?> convertDataArrayToTargetCollection(Object[] array, Class<?> collectionType, Class<?> elementType)
throws NoSuchMethodException {
Method fromMethod = elementType.getMethod("from", array.getClass().getComponentType());
Collection resultColl = CollectionFactory.createCollection(collectionType, Array.getLength(array));
Collection<Object> resultColl = CollectionFactory.createCollection(collectionType, Array.getLength(array));
for (int i = 0; i < array.length; i++) {
resultColl.add(ReflectionUtils.invokeMethod(fromMethod, null, array[i]));
}
@@ -608,6 +608,7 @@ public class MBeanClientInterceptor
this.connector.close();
}
/**
* Simple wrapper class around a method name and its signature.
* Used as the key when caching methods.
@@ -616,7 +617,7 @@ public class MBeanClientInterceptor
private final String name;
private final Class[] parameterTypes;
private final Class<?>[] parameterTypes;
/**
* Create a new instance of {@code MethodCacheKey} with the supplied
@@ -624,9 +625,9 @@ public class MBeanClientInterceptor
* @param name the name of the method
* @param parameterTypes the arguments in the method signature
*/
public MethodCacheKey(String name, Class[] parameterTypes) {
public MethodCacheKey(String name, Class<?>[] parameterTypes) {
this.name = name;
this.parameterTypes = (parameterTypes != null ? parameterTypes : new Class[0]);
this.parameterTypes = (parameterTypes != null ? parameterTypes : new Class<?>[0]);
}
@Override
@@ -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.
@@ -446,7 +446,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
objectName = JmxUtils.appendIdentityToObjectName(objectName, managedResource);
}
}
catch (Exception ex) {
catch (Throwable ex) {
throw new MBeanExportException("Unable to generate ObjectName for MBean [" + managedResource + "]", ex);
}
registerManagedResource(managedResource, objectName);
@@ -548,7 +548,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
* should be exposed to the {@code MBeanServer}. Specifically, if the
* supplied {@code mapValue} is the name of a bean that is configured
* for lazy initialization, then a proxy to the resource is registered with
* the {@code MBeanServer} so that the the lazy load behavior is
* the {@code MBeanServer} so that the lazy load behavior is
* honored. If the bean is already an MBean then it will be registered
* directly with the {@code MBeanServer} without any intervention. For
* all other beans or bean names, the resource itself is registered with
@@ -556,7 +556,8 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
* @param mapValue the value configured for this bean in the beans map;
* may be either the {@code String} name of a bean, or the bean itself
* @param beanKey the key associated with this bean in the beans map
* @return the {@code ObjectName} under which the resource was registered
* @return the {@code ObjectName} under which the resource was registered,
* or {@code null} if the actual resource was {@code null} as well
* @throws MBeanExportException if the export failed
* @see #setBeans
* @see #registerBeanInstance
@@ -577,12 +578,14 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
}
else {
Object bean = this.beanFactory.getBean(beanName);
ObjectName objectName = registerBeanInstance(bean, beanKey);
replaceNotificationListenerBeanNameKeysIfNecessary(beanName, objectName);
return objectName;
if (bean != null) {
ObjectName objectName = registerBeanInstance(bean, beanKey);
replaceNotificationListenerBeanNameKeysIfNecessary(beanName, objectName);
return objectName;
}
}
}
else {
else if (mapValue != null) {
// Plain bean instance -> register it directly.
if (this.beanFactory != null) {
Map<String, ?> beansOfSameType =
@@ -599,10 +602,11 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
return registerBeanInstance(mapValue, beanKey);
}
}
catch (Exception ex) {
catch (Throwable ex) {
throw new UnableToRegisterMBeanException(
"Unable to register MBean [" + mapValue + "] with key '" + beanKey + "'", ex);
}
return null;
}
/**
@@ -794,7 +798,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
mbean.setManagedResource(managedResource, MR_TYPE_OBJECT_REFERENCE);
return mbean;
}
catch (Exception ex) {
catch (Throwable ex) {
throw new MBeanExportException("Could not create ModelMBean for managed resource [" +
managedResource + "] with key '" + beanKey + "'", ex);
}
@@ -960,7 +964,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
}
}
}
catch (Exception ex) {
catch (Throwable ex) {
throw new MBeanExportException("Unable to register NotificationListener", ex);
}
}
@@ -980,7 +984,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
this.server.removeNotificationListener(mappedObjectName, bean.getNotificationListener(),
bean.getNotificationFilter(), bean.getHandback());
}
catch (Exception ex) {
catch (Throwable ex) {
if (logger.isDebugEnabled()) {
logger.debug("Unable to unregister NotificationListener", ex);
}
@@ -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.
@@ -72,7 +72,7 @@ public class MethodNameBasedMBeanInfoAssembler extends AbstractConfigurableMBean
* @param methodNames an array of method names indicating the methods to use
* @see #setMethodMappings
*/
public void setManagedMethods(String[] methodNames) {
public void setManagedMethods(String... methodNames) {
this.managedMethods = new HashSet<String>(Arrays.asList(methodNames));
}
@@ -85,7 +85,7 @@ public class MethodNameBasedMBeanInfoAssembler extends AbstractConfigurableMBean
*/
public void setMethodMappings(Properties mappings) {
this.methodMappings = new HashMap<String, Set<String>>();
for (Enumeration en = mappings.keys(); en.hasMoreElements();) {
for (Enumeration<?> en = mappings.keys(); en.hasMoreElements();) {
String beanKey = (String) en.nextElement();
String[] methodNames = StringUtils.commaDelimitedListToStringArray(mappings.getProperty(beanKey));
this.methodMappings.put(beanKey, new HashSet<String>(Arrays.asList(methodNames)));
@@ -138,7 +138,7 @@ public class ConnectorServerFactoryBean extends MBeanRegistrationSupport
* the {@code JMXConnectorServer} will be started in a separate thread.
* If the {@code daemon} flag is set to {@code true}, that thread will be
* started as a daemon thread.
* @throws JMException if a problem occured when registering the connector server
* @throws JMException if a problem occurred when registering the connector server
* with the {@code MBeanServer}
* @throws IOException if there is a problem starting the connector server
*/
@@ -145,7 +145,7 @@ public abstract class JmxUtils {
* @return the parameter types as classes
* @throws ClassNotFoundException if a parameter type could not be resolved
*/
public static Class[] parameterInfoToTypes(MBeanParameterInfo[] paramInfo) throws ClassNotFoundException {
public static Class<?>[] parameterInfoToTypes(MBeanParameterInfo[] paramInfo) throws ClassNotFoundException {
return parameterInfoToTypes(paramInfo, ClassUtils.getDefaultClassLoader());
}
@@ -157,12 +157,12 @@ public abstract class JmxUtils {
* @return the parameter types as classes
* @throws ClassNotFoundException if a parameter type could not be resolved
*/
public static Class[] parameterInfoToTypes(MBeanParameterInfo[] paramInfo, ClassLoader classLoader)
public static Class<?>[] parameterInfoToTypes(MBeanParameterInfo[] paramInfo, ClassLoader classLoader)
throws ClassNotFoundException {
Class[] types = null;
Class<?>[] types = null;
if (paramInfo != null && paramInfo.length > 0) {
types = new Class[paramInfo.length];
types = new Class<?>[paramInfo.length];
for (int x = 0; x < paramInfo.length; x++) {
types[x] = ClassUtils.forName(paramInfo[x].getType(), classLoader);
}
@@ -178,7 +178,7 @@ public abstract class JmxUtils {
* @return the signature as array of argument types
*/
public static String[] getMethodSignature(Method method) {
Class[] types = method.getParameterTypes();
Class<?>[] types = method.getParameterTypes();
String[] signature = new String[types.length];
for (int x = 0; x < types.length; x++) {
signature[x] = types[x].getName();
@@ -282,7 +282,7 @@ public abstract class JmxUtils {
return null;
}
String mbeanInterfaceName = clazz.getName() + MBEAN_SUFFIX;
Class[] implementedInterfaces = clazz.getInterfaces();
Class<?>[] implementedInterfaces = clazz.getInterfaces();
for (Class<?> iface : implementedInterfaces) {
if (iface.getName().equals(mbeanInterfaceName)) {
return iface;
@@ -302,7 +302,7 @@ public abstract class JmxUtils {
if (clazz == null || clazz.getSuperclass() == null) {
return null;
}
Class[] implementedInterfaces = clazz.getInterfaces();
Class<?>[] implementedInterfaces = clazz.getInterfaces();
for (Class<?> iface : implementedInterfaces) {
boolean isMxBean = iface.getName().endsWith(MXBEAN_SUFFIX);
if (mxBeanAnnotationAvailable) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,7 +24,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportAware;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
/**
@@ -46,14 +45,16 @@ public abstract class AbstractAsyncConfiguration implements ImportAware {
public void setImportMetadata(AnnotationMetadata importMetadata) {
this.enableAsync = AnnotationAttributes.fromMap(
importMetadata.getAnnotationAttributes(EnableAsync.class.getName(), false));
Assert.notNull(this.enableAsync,
"@EnableAsync is not present on importing class " + importMetadata.getClassName());
if (this.enableAsync == null) {
throw new IllegalArgumentException(
"@EnableAsync is not present on importing class " + importMetadata.getClassName());
}
}
/**
* Collect any {@link AsyncConfigurer} beans through autowiring.
*/
@Autowired(required=false)
@Autowired(required = false)
void setConfigurers(Collection<AsyncConfigurer> configurers) {
if (CollectionUtils.isEmpty(configurers)) {
return;
@@ -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.
@@ -37,16 +37,18 @@ import org.springframework.scheduling.config.ScheduledTaskRegistrar;
* &#064;Configuration
* &#064;EnableScheduling
* public class AppConfig {
*
* // various &#064;Bean definitions
* }</pre>
*
* This enables detection of @{@link Scheduled} annotations on any Spring-managed
* bean in the container. For example, given a class {@code MyTask}
* bean in the container. For example, given a class {@code MyTask}
*
* <pre class="code">
* package com.myco.tasks;
*
* public class MyTask {
*
* &#064;Scheduled(fixedRate=1000)
* public void work() {
* // task execution logic
@@ -60,6 +62,7 @@ import org.springframework.scheduling.config.ScheduledTaskRegistrar;
* &#064;Configuration
* &#064;EnableScheduling
* public class AppConfig {
*
* &#064;Bean
* public MyTask task() {
* return new MyTask();
@@ -72,6 +75,7 @@ import org.springframework.scheduling.config.ScheduledTaskRegistrar;
*
* <pre class="code">
* &#064;Configuration
* &#064;EnableScheduling
* &#064;ComponentScan(basePackages="com.myco.tasks")
* public class AppConfig {
* }</pre>
@@ -83,6 +87,7 @@ import org.springframework.scheduling.config.ScheduledTaskRegistrar;
* &#064;Configuration
* &#064;EnableScheduling
* public class AppConfig {
*
* &#064;Scheduled(fixedRate=1000)
* public void work() {
* // task execution logic
@@ -100,6 +105,7 @@ import org.springframework.scheduling.config.ScheduledTaskRegistrar;
* &#064;Configuration
* &#064;EnableScheduling
* public class AppConfig implements SchedulingConfigurer {
*
* &#064;Override
* public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
* taskRegistrar.setScheduler(taskExecutor());
@@ -111,11 +117,11 @@ import org.springframework.scheduling.config.ScheduledTaskRegistrar;
* }
* }</pre>
*
* Note in the example above the use of {@code @Bean(destroyMethod="shutdown")}. This
* ensures that the task executor is properly shut down when the Spring application
* context itself is closed.
* <p>Note in the example above the use of {@code @Bean(destroyMethod="shutdown")}.
* This ensures that the task executor is properly shut down when the Spring
* application context itself is closed.
*
* Implementing {@code SchedulingConfigurer} also allows for fine-grained
* <p>Implementing {@code SchedulingConfigurer} also allows for fine-grained
* control over task registration via the {@code ScheduledTaskRegistrar}.
* For example, the following configures the execution of a particular bean
* method per a custom {@code Trigger} implementation:
@@ -124,6 +130,7 @@ import org.springframework.scheduling.config.ScheduledTaskRegistrar;
* &#064;Configuration
* &#064;EnableScheduling
* public class AppConfig implements SchedulingConfigurer {
*
* &#064;Override
* public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
* taskRegistrar.setScheduler(taskScheduler());
@@ -150,22 +157,32 @@ import org.springframework.scheduling.config.ScheduledTaskRegistrar;
*
* <p>For reference, the example above can be compared to the following Spring XML
* configuration:
*
* <pre class="code">
* {@code
* <beans>
*
* <task:annotation-driven scheduler="taskScheduler"/>
*
* <task:scheduler id="taskScheduler" pool-size="42"/>
* <task:scheduled ref="myTask" method="work" fixed-rate="1000"/>
*
* <task:scheduled-tasks scheduler="taskScheduler">
* <task:scheduled ref="myTask" method="work" fixed-rate="1000"/>
* </task:scheduled-tasks>
*
* <bean id="myTask" class="com.foo.MyTask"/>
*
* </beans>
* }</pre>
* the examples are equivalent save that in XML a <em>fixed-rate</em> period is used
*
* The examples are equivalent save that in XML a <em>fixed-rate</em> period is used
* instead of a custom <em>{@code Trigger}</em> implementation; this is because the
* {@code task:} namespace {@code scheduled} cannot easily expose such support. This is
* but one demonstration how the code-based approach allows for maximum configurability
* through direct access to actual componentry.<p>
*
* @author Chris Beams
* @author Juergen Hoeller
* @since 3.1
* @see Scheduled
* @see SchedulingConfiguration
@@ -43,7 +43,7 @@ public class ProxyAsyncConfiguration extends AbstractAsyncConfiguration {
public AsyncAnnotationBeanPostProcessor asyncAdvisor() {
Assert.notNull(this.enableAsync, "@EnableAsync annotation metadata was not injected");
AsyncAnnotationBeanPostProcessor bpp = new AsyncAnnotationBeanPostProcessor();
Class<? extends Annotation> customAsyncAnnotation = enableAsync.getClass("annotation");
Class<? extends Annotation> customAsyncAnnotation = this.enableAsync.getClass("annotation");
if (customAsyncAnnotation != AnnotationUtils.getDefaultValue(EnableAsync.class, "annotation")) {
bpp.setAsyncAnnotationType(customAsyncAnnotation);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -55,12 +55,12 @@ import org.springframework.util.StringValueResolver;
* to the "fixedRate", "fixedDelay", or "cron" expression provided via the annotation.
*
* <p>This post-processor is automatically registered by Spring's
* {@code <task:annotation-driven>} XML element, and also by the @{@link EnableScheduling}
* annotation.
* {@code <task:annotation-driven>} XML element, and also by the
* @{@link EnableScheduling} annotation.
*
* <p>Auto-detects any {@link SchedulingConfigurer} instances in the container,
* allowing for customization of the scheduler to be used or for fine-grained control
* over task registration (e.g. registration of {@link Trigger} tasks.
* <p>Autodetects any {@link SchedulingConfigurer} instances in the container,
* allowing for customization of the scheduler to be used or for fine-grained
* control over task registration (e.g. registration of {@link Trigger} tasks.
* See the @{@link EnableScheduling} javadocs for complete usage details.
*
* @author Mark Fisher
@@ -154,9 +154,9 @@ public class ScheduledAnnotationBeanPostProcessor
}
public Object postProcessAfterInitialization(final Object bean, String beanName) {
if (!this.nonAnnotatedClasses.containsKey(bean.getClass())) {
Class<?> targetClass = AopUtils.getTargetClass(bean);
if (!this.nonAnnotatedClasses.containsKey(targetClass)) {
final Set<Method> annotatedMethods = new LinkedHashSet<Method>(1);
Class<?> targetClass = AopUtils.getTargetClass(bean);
ReflectionUtils.doWithMethods(targetClass, new MethodCallback() {
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
Scheduled scheduled = AnnotationUtils.getAnnotation(method, Scheduled.class);
@@ -167,7 +167,7 @@ public class ScheduledAnnotationBeanPostProcessor
}
});
if (annotatedMethods.isEmpty()) {
this.nonAnnotatedClasses.put(bean.getClass(), Boolean.TRUE);
this.nonAnnotatedClasses.put(targetClass, Boolean.TRUE);
}
}
return bean;
@@ -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,8 +19,8 @@ package org.springframework.scheduling.config;
import org.springframework.scheduling.Trigger;
/**
* {@link Task} implementation defining a {@code Runnable} to be executed according to a
* given {@link Trigger}.
* {@link Task} implementation defining a {@code Runnable} to be executed
* according to a given {@link Trigger}.
*
* @author Chris Beams
* @since 3.2
@@ -45,6 +45,7 @@ public class TriggerTask extends Task {
public Trigger getTrigger() {
return trigger;
return this.trigger;
}
}
@@ -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.
@@ -29,7 +29,8 @@ import java.util.TimeZone;
import org.springframework.util.StringUtils;
/**
* Date sequence generator for a <a href="http://www.manpagez.com/man/5/crontab/">Crontab pattern</a>,
* Date sequence generator for a
* <a href="http://www.manpagez.com/man/5/crontab/">Crontab pattern</a>,
* allowing clients to specify a pattern that the sequence matches.
*
* <p>The pattern is a list of six single space-separated fields: representing
@@ -41,6 +42,7 @@ import org.springframework.util.StringUtils;
* <li>"0 0 * * * *" = the top of every hour of every day.</li>
* <li>"*&#47;10 * * * * *" = every ten seconds.</li>
* <li>"0 0 8-10 * * *" = 8, 9 and 10 o'clock of every day.</li>
* <li>"0 * 6,19 * * *" = 6:00 AM and 7:00 PM every day.</li>
* <li>"0 0/30 8-10 * * *" = 8:00, 8:30, 9:00, 9:30 and 10 o'clock every day.</li>
* <li>"0 0 9-17 * * MON-FRI" = on the hour nine-to-five weekdays</li>
* <li>"0 0 0 25 12 ?" = every Christmas Day at midnight</li>
@@ -53,22 +55,22 @@ import org.springframework.util.StringUtils;
*/
public class CronSequenceGenerator {
private final BitSet seconds = new BitSet(60);
private final BitSet minutes = new BitSet(60);
private final BitSet hours = new BitSet(24);
private final BitSet daysOfWeek = new BitSet(7);
private final BitSet daysOfMonth = new BitSet(31);
private final BitSet months = new BitSet(12);
private final String expression;
private final TimeZone timeZone;
private final BitSet months = new BitSet(12);
private final BitSet daysOfMonth = new BitSet(31);
private final BitSet daysOfWeek = new BitSet(7);
private final BitSet hours = new BitSet(24);
private final BitSet minutes = new BitSet(60);
private final BitSet seconds = new BitSet(60);
/**
* Construct a {@link CronSequenceGenerator} from the pattern provided,
@@ -95,6 +97,14 @@ public class CronSequenceGenerator {
}
/**
* Return the cron pattern that this sequence generator has been built for.
*/
String getExpression() {
return this.expression;
}
/**
* Get the next {@link Date} in the sequence matching the Cron pattern and
* after the value provided. The return value will have a whole number of
@@ -106,7 +116,7 @@ public class CronSequenceGenerator {
/*
The plan:
1 Round up to the next whole second
1 Start with whole second (rounding up if necessary)
2 If seconds match move on, otherwise find the next match:
2.1 If next match is in the next minute then roll forwards
@@ -118,8 +128,6 @@ public class CronSequenceGenerator {
4 If hour matches move on, otherwise find the next match
4.1 If next match is in the next day then roll forwards,
4.2 Reset the minutes and seconds and go to 2
...
*/
Calendar calendar = new GregorianCalendar();
@@ -271,9 +279,9 @@ public class CronSequenceGenerator {
}
/**
* Replace the values in the commaSeparatedList (case insensitive) with
* their index in the list.
* @return a new string with the values from the list replaced
* Replace the values in the comma-separated list (case insensitive)
* with their index in the list.
* @return a new String with the values from the list replaced
*/
private String replaceOrdinals(String value, String commaSeparatedList) {
String[] list = StringUtils.commaDelimitedListToStringArray(commaSeparatedList);
@@ -332,6 +340,10 @@ public class CronSequenceGenerator {
range[1] = max - 1;
}
int delta = Integer.valueOf(split[1]);
if (delta <= 0) {
throw new IllegalArgumentException("Incrementer delta must be 1 or higher: '" +
field + "' in expression \"" + this.expression + "\"");
}
for (int i = range[0]; i <= range[1]; i += delta) {
bits.set(i);
}
@@ -366,28 +378,32 @@ public class CronSequenceGenerator {
throw new IllegalArgumentException("Range less than minimum (" + min + "): '" +
field + "' in expression \"" + this.expression + "\"");
}
if (result[0] > result[1]) {
throw new IllegalArgumentException("Invalid inverted range: '" + field +
"' in expression \"" + this.expression + "\"");
}
return result;
}
String getExpression() {
return this.expression;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof CronSequenceGenerator)) {
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof CronSequenceGenerator)) {
return false;
}
CronSequenceGenerator cron = (CronSequenceGenerator) obj;
return cron.months.equals(this.months) && cron.daysOfMonth.equals(this.daysOfMonth)
&& cron.daysOfWeek.equals(this.daysOfWeek) && cron.hours.equals(this.hours)
&& cron.minutes.equals(this.minutes) && cron.seconds.equals(this.seconds);
CronSequenceGenerator otherCron = (CronSequenceGenerator) other;
return (this.months.equals(otherCron.months) && this.daysOfMonth.equals(otherCron.daysOfMonth) &&
this.daysOfWeek.equals(otherCron.daysOfWeek) && this.hours.equals(otherCron.hours) &&
this.minutes.equals(otherCron.minutes) && this.seconds.equals(otherCron.seconds));
}
@Override
public int hashCode() {
return 37 + 17 * this.months.hashCode() + 29 * this.daysOfMonth.hashCode() + 37 * this.daysOfWeek.hashCode()
+ 41 * this.hours.hashCode() + 53 * this.minutes.hashCode() + 61 * this.seconds.hashCode();
return (17 * this.months.hashCode() + 29 * this.daysOfMonth.hashCode() + 37 * this.daysOfWeek.hashCode() +
41 * this.hours.hashCode() + 53 * this.minutes.hashCode() + 61 * this.seconds.hashCode());
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,21 +37,29 @@ public class CronTrigger implements Trigger {
/**
* Build a {@link CronTrigger} from the pattern provided in the default time zone.
* @param cronExpression a space-separated list of time fields,
* following cron expression conventions
* @param expression a space-separated list of time fields, following cron
* expression conventions
*/
public CronTrigger(String cronExpression) {
this.sequenceGenerator = new CronSequenceGenerator(cronExpression);
public CronTrigger(String expression) {
this.sequenceGenerator = new CronSequenceGenerator(expression);
}
/**
* Build a {@link CronTrigger} from the pattern provided.
* @param cronExpression a space-separated list of time fields,
* following cron expression conventions
* Build a {@link CronTrigger} from the pattern provided in the given time zone.
* @param expression a space-separated list of time fields, following cron
* expression conventions
* @param timeZone a time zone in which the trigger times will be generated
*/
public CronTrigger(String cronExpression, TimeZone timeZone) {
this.sequenceGenerator = new CronSequenceGenerator(cronExpression, timeZone);
public CronTrigger(String expression, TimeZone timeZone) {
this.sequenceGenerator = new CronSequenceGenerator(expression, timeZone);
}
/**
* Return the cron pattern that this trigger has been built with.
*/
public String getExpression() {
return this.sequenceGenerator.getExpression();
}
@@ -78,14 +86,11 @@ public class CronTrigger implements Trigger {
return this.sequenceGenerator.next(date);
}
public String getExpression() {
return this.sequenceGenerator.getExpression();
}
@Override
public boolean equals(Object obj) {
return (this == obj || (obj instanceof CronTrigger &&
this.sequenceGenerator.equals(((CronTrigger) obj).sequenceGenerator)));
public boolean equals(Object other) {
return (this == other || (other instanceof CronTrigger &&
this.sequenceGenerator.equals(((CronTrigger) other).sequenceGenerator)));
}
@Override
@@ -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.
@@ -114,9 +114,9 @@ public class BshScriptFactory implements ScriptFactory, BeanClassLoaderAware {
public Object getScriptedObject(ScriptSource scriptSource, Class<?>... actualInterfaces)
throws IOException, ScriptCompilationException {
try {
Class<?> clazz;
Class<?> clazz;
try {
synchronized (this.scriptClassMonitor) {
boolean requiresScriptEvaluation = (this.wasModifiedForTypeCheck && this.scriptClass == null);
this.wasModifiedForTypeCheck = false;
@@ -140,33 +140,39 @@ public class BshScriptFactory implements ScriptFactory, BeanClassLoaderAware {
}
clazz = this.scriptClass;
}
}
catch (EvalError ex) {
this.scriptClass = null;
throw new ScriptCompilationException(scriptSource, ex);
}
if (clazz != null) {
// A Class: We need to create an instance for every call.
try {
return clazz.newInstance();
}
catch (Throwable ex) {
throw new ScriptCompilationException(
scriptSource, "Could not instantiate script class: " + clazz.getName(), ex);
}
if (clazz != null) {
// A Class: We need to create an instance for every call.
try {
return clazz.newInstance();
}
else {
// Not a Class: We need to evaluate the script for every call.
catch (Throwable ex) {
throw new ScriptCompilationException(
scriptSource, "Could not instantiate script class: " + clazz.getName(), ex);
}
}
else {
// Not a Class: We need to evaluate the script for every call.
try {
return BshScriptUtils.createBshObject(
scriptSource.getScriptAsString(), actualInterfaces, this.beanClassLoader);
}
}
catch (EvalError ex) {
throw new ScriptCompilationException(scriptSource, ex);
catch (EvalError ex) {
throw new ScriptCompilationException(scriptSource, ex);
}
}
}
public Class<?> getScriptedObjectType(ScriptSource scriptSource)
throws IOException, ScriptCompilationException {
try {
synchronized (this.scriptClassMonitor) {
synchronized (this.scriptClassMonitor) {
try {
if (scriptSource.isModified()) {
// New script content: Let's check whether it evaluates to a Class.
this.wasModifiedForTypeCheck = true;
@@ -174,9 +180,10 @@ public class BshScriptFactory implements ScriptFactory, BeanClassLoaderAware {
}
return this.scriptClass;
}
}
catch (EvalError ex) {
throw new ScriptCompilationException(scriptSource, ex);
catch (EvalError ex) {
this.scriptClass = null;
throw new ScriptCompilationException(scriptSource, ex);
}
}
}
@@ -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.
@@ -39,13 +39,13 @@ import org.springframework.util.xml.DomUtils;
* Allows for objects written using dynamic languages to be easily exposed with
* the {@link org.springframework.beans.factory.BeanFactory}.
*
* <p>The script for each object can be specified either as a reference to the Resource
* containing it (using the '{@code script-source}' attribute) or inline in the XML configuration
* itself (using the '{@code inline-script}' attribute.
* <p>The script for each object can be specified either as a reference to the
* resource containing it (using the '{@code script-source}' attribute) or inline
* in the XML configuration itself (using the '{@code inline-script}' attribute.
*
* <p>By default, dynamic objects created with these tags are <strong>not</strong> refreshable.
* To enable refreshing, specify the refresh check delay for each object (in milliseconds) using the
* '{@code refresh-check-delay}' attribute.
* <p>By default, dynamic objects created with these tags are <strong>not</strong>
* refreshable. To enable refreshing, specify the refresh check delay for each
* object (in milliseconds) using the '{@code refresh-check-delay}' attribute.
*
* @author Rob Harrop
* @author Rod Johnson
@@ -171,14 +171,13 @@ class ScriptBeanDefinitionParser extends AbstractBeanDefinitionParser {
// Attach any refresh metadata.
String refreshCheckDelay = element.getAttribute(REFRESH_CHECK_DELAY_ATTRIBUTE);
if (StringUtils.hasText(refreshCheckDelay)) {
bd.setAttribute(ScriptFactoryPostProcessor.REFRESH_CHECK_DELAY_ATTRIBUTE, new Long(refreshCheckDelay));
bd.setAttribute(ScriptFactoryPostProcessor.REFRESH_CHECK_DELAY_ATTRIBUTE, Long.valueOf(refreshCheckDelay));
}
// Attach any proxy target class metadata.
String proxyTargetClass = element.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE);
if (StringUtils.hasText(proxyTargetClass)) {
Boolean flag = new Boolean(proxyTargetClass);
bd.setAttribute(ScriptFactoryPostProcessor.PROXY_TARGET_CLASS_ATTRIBUTE, flag);
bd.setAttribute(ScriptFactoryPostProcessor.PROXY_TARGET_CLASS_ATTRIBUTE, Boolean.valueOf(proxyTargetClass));
}
// Add constructor arguments.
@@ -213,7 +212,7 @@ class ScriptBeanDefinitionParser extends AbstractBeanDefinitionParser {
*/
private String resolveScriptSource(Element element, XmlReaderContext readerContext) {
boolean hasScriptSource = element.hasAttribute(SCRIPT_SOURCE_ATTRIBUTE);
List elements = DomUtils.getChildElementsByTagName(element, INLINE_SCRIPT_ELEMENT);
List<Element> elements = DomUtils.getChildElementsByTagName(element, INLINE_SCRIPT_ELEMENT);
if (hasScriptSource && !elements.isEmpty()) {
readerContext.error("Only one of 'script-source' and 'inline-script' should be specified.", element);
return null;
@@ -222,7 +221,7 @@ class ScriptBeanDefinitionParser extends AbstractBeanDefinitionParser {
return element.getAttribute(SCRIPT_SOURCE_ATTRIBUTE);
}
else if (!elements.isEmpty()) {
Element inlineElement = (Element) elements.get(0);
Element inlineElement = elements.get(0);
return "inline:" + DomUtils.getTextValue(inlineElement);
}
else {
@@ -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.
@@ -40,7 +40,7 @@ public class ScriptingDefaultsParser implements BeanDefinitionParser {
LangNamespaceUtils.registerScriptFactoryPostProcessorIfNecessary(parserContext.getRegistry());
String refreshCheckDelay = element.getAttribute(REFRESH_CHECK_DELAY_ATTRIBUTE);
if (StringUtils.hasText(refreshCheckDelay)) {
bd.getPropertyValues().add("defaultRefreshCheckDelay", new Long(refreshCheckDelay));
bd.getPropertyValues().add("defaultRefreshCheckDelay", Long.valueOf(refreshCheckDelay));
}
String proxyTargetClass = element.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE);
if (StringUtils.hasText(proxyTargetClass)) {
@@ -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.
@@ -24,7 +24,6 @@ import groovy.lang.MetaClass;
import groovy.lang.Script;
import org.codehaus.groovy.control.CompilationFailedException;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
@@ -99,7 +98,7 @@ public class GroovyScriptFactory implements ScriptFactory, BeanFactoryAware, Bea
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
public void setBeanFactory(BeanFactory beanFactory) {
if (beanFactory instanceof ConfigurableListableBeanFactory) {
((ConfigurableListableBeanFactory) beanFactory).ignoreDependencyType(MetaClass.class);
}
@@ -151,10 +150,9 @@ public class GroovyScriptFactory implements ScriptFactory, BeanFactoryAware, Bea
public Object getScriptedObject(ScriptSource scriptSource, Class<?>... actualInterfaces)
throws IOException, ScriptCompilationException {
try {
Class<?> scriptClassToExecute;
synchronized (this.scriptClassMonitor) {
synchronized (this.scriptClassMonitor) {
try {
Class<?> scriptClassToExecute;
this.wasModifiedForTypeCheck = false;
if (this.cachedResult != null) {
@@ -179,21 +177,23 @@ public class GroovyScriptFactory implements ScriptFactory, BeanFactoryAware, Bea
}
}
scriptClassToExecute = this.scriptClass;
}
// Process re-execution outside of the synchronized block.
return executeScript(scriptSource, scriptClassToExecute);
}
catch (CompilationFailedException ex) {
throw new ScriptCompilationException(scriptSource, ex);
// Process re-execution outside of the synchronized block.
return executeScript(scriptSource, scriptClassToExecute);
}
catch (CompilationFailedException ex) {
this.scriptClass = null;
this.scriptResultClass = null;
throw new ScriptCompilationException(scriptSource, ex);
}
}
}
public Class<?> getScriptedObjectType(ScriptSource scriptSource)
throws IOException, ScriptCompilationException {
try {
synchronized (this.scriptClassMonitor) {
synchronized (this.scriptClassMonitor) {
try {
if (this.scriptClass == null || scriptSource.isModified()) {
// New script content...
this.wasModifiedForTypeCheck = true;
@@ -212,9 +212,12 @@ public class GroovyScriptFactory implements ScriptFactory, BeanFactoryAware, Bea
}
return this.scriptResultClass;
}
}
catch (CompilationFailedException ex) {
throw new ScriptCompilationException(scriptSource, ex);
catch (CompilationFailedException ex) {
this.scriptClass = null;
this.scriptResultClass = null;
this.cachedResult = null;
throw new ScriptCompilationException(scriptSource, ex);
}
}
}

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