Compare commits

...

147 Commits

Author SHA1 Message Date
Spring Builds 23bb745ea4 Release v5.3.13 2021-11-11 07:31:25 +00:00
Arjen Poutsma 9197f15a30 Use ByteArrayDecoder in DefaultClientResponse::createException
This commit changes DefaultClientResponse::createException to use
the ByteArrayDecoder, instead of converting to DataBuffers and
turning these into a byte array.

Closes gh-27666
2021-11-10 16:24:49 +01:00
Juergen Hoeller 15a6373fed Avoid nullability warnings 2021-11-10 14:22:06 +01:00
Juergen Hoeller 2a268701c4 Introduce optimizeLocations flag for resource location filtering on startup
This flag is off by default since it requires jar files with directory entries.

Closes gh-27624
2021-11-10 14:21:48 +01:00
Juergen Hoeller 11a0df3fd1 Upgrade to Tomcat 9.0.54, Netty 4.1.70, HtmlUnit 2.54, XMLUnit 2.8.3 2021-11-09 22:36:11 +01:00
Juergen Hoeller b167e1a93f Remove unnecessary final declarations (for consistency) 2021-11-09 22:35:24 +01:00
Juergen Hoeller 8d735e6e60 Note on PersistenceExceptionTranslator sorting and non-singleton retrieval
Closes gh-26412
2021-11-09 22:30:44 +01:00
Juergen Hoeller 9bc09631d6 Recommend ObjectProvider as alternative to @Lazy for optional dependencies
Closes gh-27649
2021-11-09 22:29:56 +01:00
Stephane Nicoll 39be572a7a Upgrade to Reactor 2020.0.13
Closes gh-27636
2021-11-09 19:38:10 +01:00
Abdullah Khan 6ac780d595 Fix grammar in webflux-webclient.adoc
Closes gh-27657
2021-11-09 14:22:50 +01:00
Rossen Stoyanchev c6ce65ef56 Polishing contribution
Closes gh-27623
2021-11-09 09:47:02 +00:00
happyWilliam0 b5743966d6 Improve efficiency of UrlPathHelper#getSanitizedPath
See gh-27623
2021-11-09 09:47:02 +00:00
Rossen Stoyanchev c5de5c9939 Update Javadoc of LogFormatUtils
Closes gh-27632
2021-11-08 21:21:54 +00:00
Sam Brannen ff1485fd8d Fix log message formatting in CandidateComponentsIndexLoader 2021-11-05 10:31:10 +01:00
Stephane Nicoll 1b4438caac Start building against Reactor 2020.0.13 snapshots
See gh-27636
2021-11-04 14:47:37 +01:00
Arjen Poutsma 0c7e000250 Refactor Contents to DefaultParts
This commit moves the Contents abstraction into DefaultParts

See gh-27613
2021-11-03 15:02:12 +01:00
Arjen Poutsma 694db2273f Add Part::delete method
This commit introduces the Part::delete method, that deletes its
underlying storage.

Closes gh-27612
2021-11-02 16:15:44 +01:00
Stephane Nicoll 47d3819eab Merge pull request #27604 from Xjzon
* pr/27604:
  Polish "Add support for custom expression parsing"
  Add support for custom expression parsing

Closes gh-27604
2021-10-28 14:21:29 +02:00
Stephane Nicoll f295c8b2fb Polish "Add support for custom expression parsing"
See gh-27604
2021-10-28 14:20:15 +02:00
Xjzon 40d84c297b Add support for custom expression parsing
See gh-27604
2021-10-28 13:57:15 +02:00
Arjen Poutsma 0416168d0e Fix bug in max header calculation in DefaultPartHttpMessageReader
This commit fixes a bug in the DefaultPartHttpMessageReader, in the
check for exceeding the maximum header size. Before this commit, the
entire buffer size was considered, thus triggering an exception even
though the max header limit was not exceeded. After this commit, we only
consider the size up until the end-of-header mark (CRLFCRLF).

Furthermore, this commit increases the default maximum header size to
10k, the same default as Commons File upload.

Closes gh-27612
2021-10-27 16:28:32 +02:00
Sam Brannen c4c3d59d07 Remove unused code in FormattingConversionServiceTests 2021-10-25 17:02:58 +02:00
Сергей Цыпанов 0268e76298 Improve mapping function in ExtendedEntityManagerCreator.createProxy()
Closes gh-27456
2021-10-25 16:30:26 +02:00
Kenzo Spaulding 4ec8ae42f4 Add test cases to SpEL's MapAccessorTests
Closes gh-26981
2021-10-23 17:45:37 +02:00
Sam Brannen 995aaa6159 Polishing 2021-10-23 16:08:00 +02:00
Sam Brannen 2c89ff934d Update copyright date
See gh-27560
2021-10-23 15:59:46 +02:00
Daniil Pozdeev c58853f5e5 Use LocalDataSourceJobStore only if one is not set via Quartz properties
Prior to this commit, Spring's SchedulerFactoryBean always set the
"org.quartz.jobStore.class" property to LocalDataSourceJobStore even if
the user had already specified a custom JobStore implementation via the
Quartz properties file or Properties object, thereby effectively
ignoring the user configuration.

This commit addresses this by configuring Quartz to use Spring's
LocalDataSourceJobStore only if a JobStore has not already been
specified via user configuration.

Closes gh-27560
2021-10-23 15:22:42 +02:00
xxpain 66826ac960 Fix typo in Javadoc in HeaderAssertions
Closes gh-27589
2021-10-22 15:28:27 +02:00
Sam Brannen a603779f33 Return previous value in UndertowHeadersAdapter's remove() method
Prior to this commit, UndertowHeadersAdapter's remove() method violated
the java.util.Map contract by always returning null.

This commit fixes this by returning the previous list stored under the
specified key, and otherwise returning null if no previous value was
present.

Closes gh-27592
2021-10-22 14:57:12 +02:00
Сергей Цыпанов e5475d698a Iterate over Map's entrySet() instead of keySet() in PropertyEditorRegistrySupport
Closes gh-27591
2021-10-22 14:15:33 +02:00
Sam Brannen b728b4640b Add explicit tests for SpEL functions for fix for gh-27582 2021-10-22 13:46:11 +02:00
Sam Brannen bc657eb4d5 Fix SpEL vararg method invocation for strings containing commas
Prior to this commit, if a SpEL expression invoked a method or
registered function that declares a String varargs argument, there were
sometimes issues with converting the input arguments into the varargs
array argument. Specifically, if the expression supplied a single
String argument containing a comma for the varargs (such as "a,b"),
SpEL's ReflectionHelper.convertArguments() method incorrectly converted
that single String to an array via the ConversionService, which
indirectly converted that String using the StringToArrayConverter,
which converts a comma-delimited String to an array. Thus, "a,b"
effectively got converted to a two-dimensional array ["a", "b"] instead
of simply ["a,b"].

This commit fixes this bug by avoiding use of the TypeConverter and
ConversionService for single arguments supplied as varargs when the
single argument's type matches the varargs array component type.

Closes gh-27582
2021-10-22 13:13:13 +02:00
Sam Brannen 9b967775ed Polish Spel's ReflectionHelper.setupArgumentsForVarargsInvocation() 2021-10-22 11:08:45 +02:00
Sam Brannen 9af11ad5ce Fix Javadoc formatting issues 2021-10-22 11:08:45 +02:00
Sam Brannen 7a54ff2d21 Extract public TypeFilterUtils from ComponentScanAnnotationParser
Prior to this commit, third parties using @ComponentScan's @Filter
annotation had to implement their own parsing for @Filter
AnnotationAttributes as well as instantiation of the corresponding
TypeFilters. In such cases the various *Aware callbacks
(BeanFactoryAware, EnvironmentAware, etc.) should also be supported.

This commit therefore extracts a new public TypeFilterUtils class from
ComponentScanAnnotationParser so that third parties can benefit from
consistent TypeFilter creation from @ComponentScan @Filter annotations.

Closes gh-27553
2021-10-21 14:15:38 +02:00
Sam Brannen ec3f857bda Polish contribution
See gh-27586
2021-10-21 12:40:10 +02:00
no-brand b3eb1a2ad7 Improve example in Javadoc for HttpEntity
Closes gh-27586
2021-10-21 12:35:59 +02:00
Spring Builds bce850aa12 Next development version (v5.3.13-SNAPSHOT) 2021-10-21 05:57:00 +00:00
Sam Brannen 3d6d8a947a Update "Reporting a Vulnerability" link 2021-10-20 14:48:51 +02:00
Sam Brannen 6fa6bfe421 Fix link to Spring Framework project page in Javadoc overview 2021-10-19 16:46:01 +02:00
Rossen Stoyanchev 05ea991d62 Removing locations logging in ResourceHttpRequestHandler
See gh-27575
2021-10-19 12:25:33 +01:00
Arjen Poutsma a248a52575 Revert transitive MediaType comparators
The fix made for gh-27488 resulted in a change of the default order
of codecs. This commit reverts these changes, so that the previous
order is restored.

Closes gh-27573
2021-10-19 11:53:22 +02:00
Arjen Poutsma 2a3c9e403f Revert "Polishing"
This reverts commit bfa01b35df.
2021-10-19 10:16:27 +02:00
Rossen Stoyanchev bad87be306 Fix checkstyle warning
See gh-27569
2021-10-18 17:04:11 +01:00
Rossen Stoyanchev 346b755802 Fix assertion message in DefaultDataBuffer
Closes gh-27567
2021-10-18 16:54:24 +01:00
Smile 4978eeff7f Update Javadoc in DefaultResponseErrorHandler
Closes gh-27569
2021-10-18 16:26:48 +01:00
Sam Brannen 052ed50f48 Fix copy-and-paste error in Javadoc 2021-10-17 19:33:42 +02:00
Rossen Stoyanchev 76c9306dda Adjust logging of resource locations 2021-10-14 17:18:34 +01:00
Sam Brannen 0853baaa3f Fix Javadoc in [NamedParameter]JdbcOperations.queryForObject methods
This commit fixes the Javadoc in all queryForObject(...) methods in
JdbcOperations and NamedParameterJdbcOperations regarding what kinds of
exceptions are thrown under which conditions.

Closes gh-27559
2021-10-14 15:15:23 +02:00
Spring Builds bf461ba0b2 Next development version (v5.3.12-SNAPSHOT) 2021-10-14 09:35:45 +00:00
Rossen Stoyanchev 0705454ce0 Fix typo in Javadoc
See gh-27484
2021-10-14 09:42:40 +01:00
Rossen Stoyanchev a178bbe86f DefaultResponseErrorHandler shows full error details
Closes gh-27552
2021-10-13 20:51:34 +01:00
Sam Brannen fcf4315e02 Indent with tabs instead of spaces 2021-10-13 20:04:40 +02:00
Sam Brannen 89c7797ffb Commit in DatabasePopulatorUtils if Connection has auto-commit=false
Prior to this commit, DatabasePopulatorUtils.execute(...) did not
perform a commit for the current Connection. This works for most use
cases; however, when DatabasePopulatorUtils is used to execute
initialization scripts without a managed transaction -- for example,
via a DataSourceInitializer configured as a bean in the
ApplicationContext or via Spring Boot configuration in
application.properties -- if the underlying database is configured with
auto-commit=false, the results of executing the SQL scripts are not
committed to the database which can lead to data being silently lost.

This commit addresses this issue by committing the Connection for the
supplied DataSource if the connection is not configured for auto-commit
and is not transactional. Existing use cases running with a managed
transaction should therefore not be affected by this change.

Closes gh-27008
2021-10-13 19:10:09 +02:00
Rossen Stoyanchev 4dac8339ff Filter non-existing static resource locations
Same as a2c52a97ba, on the WebFlux side.

See gh-27538
2021-10-13 14:40:34 +01:00
Rossen Stoyanchev 0436dd04bf Correctly handle coroutine with ResponseEntity
ResponseEntityResultHandler nests correctly, only once for the ResponseEntity,
when there is a Mono adapted from a Kotlin Continuation.

Closes gh-27292
2021-10-13 14:40:34 +01:00
Hantsy Bai 1e3996ea78 Upgrade SmallRye Mutiny to 1.1.1
Closes gh-27555
2021-10-13 15:27:02 +02:00
Koen Punt 50b92118a9 Include correct keyword in CookieAssertions failure messages
Closes gh-27550
2021-10-13 14:02:55 +02:00
Juergen Hoeller b1c7f7d127 Polishing 2021-10-13 12:48:47 +02:00
Juergen Hoeller 0f36569d75 Remove dead fallback code 2021-10-13 12:38:39 +02:00
Juergen Hoeller 2cbba0923b Upgrade to Netty 4.1.69, Jetty 9.4.44, Kotlin 1.5.31 2021-10-13 12:38:06 +02:00
Rossen Stoyanchev 800922266a Upgrade to Reactor 2021.0.12
Closes gh-27527
2021-10-12 16:23:18 +01:00
Juergen Hoeller eda3ca5fbc Remove unnecessary final declarations at method level 2021-10-12 15:17:44 +02:00
Juergen Hoeller e4934a90eb Use TriggerContext's Clock instead of new Date()
Closes gh-27546
2021-10-12 15:17:18 +02:00
Juergen Hoeller 715f300fa1 Avoid expensive isReadable() check during classpath scan
Closes gh-25741
See gh-21372
2021-10-12 15:15:51 +02:00
Juergen Hoeller b53275f2d2 Add efficient existence check to ClassPathResource.isReadable()
Includes reduced isReadable() check in PathResourceLookupFunction, aligned with PathResourceResolver.

Closes gh-27538
See gh-21372
2021-10-12 15:13:05 +02:00
Juergen Hoeller 1490d27d75 Decouple urlResourceWithCharset test from existence of tmp directory
See gh-25738
2021-10-12 15:10:19 +02:00
Rossen Stoyanchev a2c52a97ba Filter non-existing static resource locations
See gh-27538
2021-10-12 11:59:55 +01:00
Sam Brannen 5bd90538b3 Introduce test for gh-27499 and polish contribution 2021-10-12 12:22:24 +02:00
Nick 50ccb1bfcd Avoid duplicate JCacheOperationSource bean registration in <cache:annotation-driven />
In our application we use XML context and <cache:annotation-driven />
declaration. Also we disable bean definition duplication by setting
GenericApplicationContext.setAllowBeanDefinitionOverriding(false) in an
ApplicationContextInitializer. This combination leads to a
BeanDefinitionOverrideException because the
DefaultJCacheOperationSource bean is registered twice.

 - once for: parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
 - once for: parserContext.registerBeanComponent(new BeanComponentDefinition(sourceDef, sourceName));

This commit refactors JCacheCachingConfigurer.registerCacheAspect(...)
so that the JCacheOperationSource bean is registered only once.

Closes gh-27499
2021-10-12 12:05:30 +02:00
Stephane Nicoll 83eac9af18 Upgrade CI to github-release resource 1.5.5
Closes gh-27459
2021-10-11 16:18:35 +02:00
Sam Brannen eb07dea795 Polish contribution
See gh-27544
2021-10-11 15:31:40 +02:00
Сергей Цыпанов 114fa47171 Use Arrays.hashCode() in ByteArrayResource.hashCode() 2021-10-11 15:28:50 +02:00
Sam Brannen 63fac1b7c8 Allow default CacheAwareContextLoaderDelegate configuration via system property
Prior to this commit, the default CacheAwareContextLoaderDelegate could
be configured by extending AbstractTestContextBootstrapper and
overriding getCacheAwareContextLoaderDelegate(); however, this required
that the user configure the custom TestContextBootstrapper via
@BootstrapWith.

This commit introduces a new
"spring.test.context.default.CacheAwareContextLoaderDelegate" property
that can be configured via a JVM system property or via the
SpringProperties mechanism. BootstrapUtils uses this new property to
load the default CacheAwareContextLoaderDelegate. If the property is
not defined, BootstrapUtils will fall back to creating a
DefaultCacheAwareContextLoaderDelegate as it did previously.

This allows third parties to configure the default
CacheAwareContextLoaderDelegate transparently for the user -- for
example, to intercept context loading in order to load the context in a
different manner -- for example, to make use of ahead of time (AOT)
techniques for implementing a different type of ApplicationContext at
build time.

Closes gh-27540
2021-10-11 14:59:09 +02:00
Rossen Stoyanchev e8f6cd10a5 Apply value formatting to resolved exceptions 2021-10-11 11:14:02 +01:00
Sam Brannen 47b8e8d528 Upgrade to Mockito 4 2021-10-10 23:26:07 +02:00
Sam Brannen bdfd983bb4 Fix example code formatting in @EnableWebMvc 2021-10-08 21:30:39 +02:00
Juergen Hoeller 87aaf5049b Polishing 2021-10-08 20:41:51 +02:00
Juergen Hoeller 4b01370f54 UriTemplateRequestEntity overrides equals/hashCode
Closes gh-27531
2021-10-08 20:41:18 +02:00
Rossen Stoyanchev b6111d04a5 Ensure WebClientResponseException for malformed response
Closes gh-27262
2021-10-07 16:50:53 +01:00
Ashley Scopes 9bd989f1bb WebClient tests for socket and response format issues
Added test case for malformed response chunk, which is
now failing as expected.

See gh-27262
2021-10-07 16:50:53 +01:00
Stephane Nicoll d5597a75a6 Start building against Reactor 2020.0.12 snapshots
See gh-27527
2021-10-07 08:51:32 +02:00
Rossen Stoyanchev 90fdcf88d8 Generalize formatValue
Provide an overload for additional control and compact output.
2021-10-06 21:27:56 +01:00
Sam Brannen 5d3b16cd3a Indent with tabs instead of spaces 2021-10-06 15:42:52 +02:00
Sam Brannen 41ae9632d1 Upgrade to Checkstyle 9.0 and spring-javaformat 0.0.29
This commit upgrades the Gradle build to use Checkstyle 9.0 and
spring-javaformat 0.0.29 (which internally uses Checkstyle 8.45.1).

Closes gh-27520
2021-10-06 12:11:19 +02:00
Sam Brannen 47b0da6b25 Polishing 2021-10-06 11:48:30 +02:00
Arjen Poutsma c99210c01f Propagate Reactor Context when using FluxSink
This commit makes sure that the Reactor context from a given mono or
flux is propagated to the Flux returned by a FluxSink. This change
affects both DataBufferUtils::write and internal classes used by the
DefaultPartHttpMessageReader.

Closes gh-27517
2021-10-05 16:30:49 +02:00
Rossen Stoyanchev 7b9848a352 Replace deprecated Reactor Context related methods 2021-10-05 14:33:52 +01:00
Sam Brannen 0e83466023 Reference Hamcrest Javadoc via javadoc.io
Due to an SSL/TLS issue with hamcrest.org, the Dokka task fails with the
following.

> Failed to download package-list from https://hamcrest.org/JavaHamcrest/javadoc/2.1/package-list,
> this might suggest that remote resource is not available, module is
> empty or dokka output got corrupted

See: https://github.com/hamcrest/JavaHamcrest/issues/280

As a workaround, this commit switches to javadoc.io to reference the
Hamcrest Javadoc APIs.
2021-10-05 15:23:44 +02:00
Sam Brannen 48a507a993 Clean up warnings 2021-10-05 14:35:32 +02:00
Sam Brannen be3bc4c164 Comment out unused fudgeFactor 2021-10-05 14:24:18 +02:00
Rossen Stoyanchev e68219c1ac ResponseStatusExceptionHandler logs exception message only
No need to log the full exception for a resolved exception, and as the
comment suggests that it mirrors Spring MVC equivalent, which also
logs the message only.
2021-10-05 12:12:17 +01:00
Stephane Nicoll 151852b164 Upgrade to GitHub Changelog Generator 0.0.7 in CI
Closes gh-27512
2021-10-03 07:09:24 +02:00
Juergen Hoeller 49427b0c3c Upgrade to Apache Johnzon 1.2.14, Vavr 0.10.4, WebJars Locator 0.48, HtmlUnit 2.53 2021-10-02 12:08:09 +02:00
Juergen Hoeller bf373c5065 Skip all flaky StopWatch time assertions 2021-10-02 12:04:13 +02:00
Sam Brannen 678fd8344e Polishing 2021-10-01 14:37:07 +02:00
Juergen Hoeller f632165dec Invoke bean-derived (Auto)Closeable.close() method directly
Closes gh-27504
2021-10-01 13:26:25 +02:00
Sam Brannen fd11789db9 Polish JSR-107 caching ref docs 2021-10-01 12:51:52 +02:00
Jens Schauder d6ec6f0fe9 Remove remark about missing caching API. 2021-10-01 11:56:36 +02:00
Sam Brannen 7311ae19be Fix build by disabling linking to JUnit 5.8.1 Javadoc
The `package-list` file no longer exists at
https://junit.org/junit5/docs/5.8.1/api/, due to the following commit.

https://github.com/junit-team/junit5/commit/67ad4e545518b0ce2b0e7c96df31a669866d5003
2021-10-01 11:09:59 +02:00
Sam Brannen f0aa4f4857 Escape closing curly braces in regular expressions for Android support
PR gh-24470 introduced a regression for Android users by no longer
escaping closing curly braces in regular expressions.

This commit therefore partially reverts the changes made in 273812f9c5
for closing curly braces (`}`).

Closes gh27467
2021-10-01 10:35:28 +02:00
Juergen Hoeller f64f07049d Upgrade to SLF4J 1.7.32 2021-09-30 18:12:10 +02:00
Juergen Hoeller 24bcb52b2f Polishing 2021-09-30 18:09:07 +02:00
Juergen Hoeller 4f44ae3f28 Polishing 2021-09-30 17:34:22 +02:00
Juergen Hoeller a295a28e4b Defensively handle fast class generation failure for individual methods
Includes rethrowing of last actual defineClass exception encountered.

Closes gh-27490
2021-09-30 17:33:58 +02:00
Arjen Poutsma bfa01b35df Polishing
See gh-27488
2021-09-30 17:09:03 +02:00
Arjen Poutsma 388c8e4aa5 Make sure that MediaType comparators are transitive
Previous to this commit, the specificity and quality comparators
(used by MediaType::sortByQualityValue and MediaType::sortBySpecificity)
could result in IllegalArgumentExceptions when used for sorting.
The underlying reason was that the comparators were not transitive, and
both media types with the same type, and types with the same amount of
parameters, would be considered identical by the comparator (result 0).

This commit ensures that the comparators are transitive.

Closes gh-27488
2021-09-30 16:15:38 +02:00
Sam Brannen 96e4d3a530 Fail Gradle build for Javadoc warnings
In order to catch Javadoc errors in the build, we now enable the
`Xwerror` flag for the `javadoc` tool. In addition, we now use
`Xdoclint:syntax` instead of `Xdoclint:none` in order to validate
syntax within our Javadoc.

This commit fixes all resulting Javadoc errors and warnings.

This commit also upgrades to Undertow 2.2.12.Final and fixes the
artifact names for exclusions for the Servlet and annotations APIs.

The incorrect exclusion of the Servlet API resulted in the Servlet API
being on the classpath twice for the javadoc task, which resulted in the
following warnings in previous builds.

javadoc: warning - Multiple sources of package comments found for package "javax.servlet"
javadoc: warning - Multiple sources of package comments found for package "javax.servlet.http"
javadoc: warning - Multiple sources of package comments found for package "javax.servlet.descriptor"
javadoc: warning - Multiple sources of package comments found for package "javax.servlet.annotation"

Closes gh-27480
2021-09-29 14:02:37 +02:00
Juergen Hoeller 040445612f Polishing 2021-09-28 18:15:56 +02:00
Juergen Hoeller 86b010a6b2 Defensive reference to JNDI API for JDK 9+ (optional java.naming module)
Closes gh-27483
2021-09-28 18:15:22 +02:00
Juergen Hoeller 2feedb98cc Remove lineSeparator LF requirement (accept LF/CR/CRLF by default)
See gh-27481
2021-09-28 18:15:00 +02:00
Arjen Poutsma 3be2b32e21 Remove only leading space for SSE data
Prior to this commit, all white space was trimmed from Server Sent Event
data. After this commit, only a leading space is removed (if present).

Closes gh-27473
2021-09-28 14:56:39 +02:00
Sam Brannen 85bdea6f47 Fix code formatting in Javadoc
See gh-27480
2021-09-28 13:41:25 +02:00
Sam Brannen bfdc99ab79 Fix Javadoc errors
See gh-27480
2021-09-28 11:44:12 +02:00
Sam Brannen 2567b20949 Upgrade to spring-javaformat 0.0.28 and downgrade to Checkstyle 8.41
In order to be able to use text blocks and other new Java language
features, we are upgrading to a recent version of Checkstyle.

The latest version of spring-javaformat-checkstyle (0.0.28) is built
against Checkstyle 8.32 which does not include support for language
features such as text blocks. Support for text blocks was added in
Checkstyle 8.36.

In addition, there is a binary compatibility issue between
spring-javaformat-checkstyle 0.0.28 and Checkstyle 8.42. Thus we cannot
use Checkstyle 8.42 or higher.

In this commit, we therefore upgrade to spring-javaformat-checkstyle
0.0.28 and downgrade to Checkstyle 8.41.

This change is being applied to `5.3.x` as well as `main` in order to
benefit from the enhanced checking provided in more recent versions of
Checkstyle.

Closes gh-27481
2021-09-28 10:29:31 +02:00
Juergen Hoeller 119c78b1c9 Skip flaky StopWatch time assertions 2021-09-27 17:11:12 +02:00
Juergen Hoeller d8e18f56e1 Upgrade to Protobuf 3.18, Rome 1.16, BlockHound 1.0.6, Caffeine 2.9.2, Groovy 3.0.9, Tomcat 9.0.53 2021-09-27 17:01:18 +02:00
Juergen Hoeller 211f0bbf88 Fix invalid characters in source files
Closes gh-27475
2021-09-27 16:57:54 +02:00
Juergen Hoeller b0c424b376 Deprecate RxJava 2 in favor of RxJava 3
Closes gh-27474
2021-09-27 16:56:28 +02:00
Juergen Hoeller 9ff0d717f2 Restore lenient fallback in case of several non-public constructors
See gh-27437
2021-09-27 16:52:11 +02:00
Rossen Stoyanchev 93f8706dd3 Update docs for ControllerAdvice
In 5.3 it became possible to handle exceptions from any handler through
ExceptionHandler's in a ControllerAdvice class, but this is not
mentioned in the docs

See gh-22619, gh-27338
2021-09-24 15:57:15 +01:00
Juergen Hoeller e29cfa3501 Polishing 2021-09-23 15:57:43 +02:00
Juergen Hoeller 208fafa4a3 Fix contract violations in ConcurrentReferenceHashMap's EntrySet/Iterator
Closes gh-27454
2021-09-23 15:56:49 +02:00
Juergen Hoeller 5cbc972a0d Log rejected listener container tasks at warn level
Closes gh-27451
2021-09-23 15:56:06 +02:00
Juergen Hoeller 58898de542 Provide accessors for externallyManagedConfigMembers and Init/DestroyMethods
Closes gh-27449
2021-09-23 15:54:40 +02:00
Juergen Hoeller f9d63e7bb1 BeanUtils.getResolvableConstructor falls back to single non-public constructor
Closes gh-27437
2021-09-23 15:53:54 +02:00
Sam Brannen 134c0e2916 Upgrade to JUnit 5.8.1
Closes gh-27450
2021-09-22 22:08:38 +02:00
Juergen Hoeller 1f8c233dfc Polishing 2021-09-21 17:43:03 +02:00
Juergen Hoeller 0dc5d2794f Avoid early ConversionService determination in StandardBeanExpressionResolver
Closes gh-27446
2021-09-21 17:42:50 +02:00
Juergen Hoeller 49d003857d Skip CGLIB class validation in case of optimize flag
Closes gh-27439
2021-09-21 17:42:19 +02:00
Juergen Hoeller eabe946a53 Skip readStream optimization for compatibility with misbehaving InputStreams
Closes gh-27429
2021-09-21 17:41:56 +02:00
Sam Brannen 09a1b87d37 About notes about AJDT and Kotlin not supported in Eclipse 4.21
See gh-27407
2021-09-21 14:23:02 +02:00
Sam Brannen 34abc8f577 The Kotlin plugin is no longer required for development in Eclipse
As documented, it's only required if you with to run Kotlin tests or
develop Kotlin extensions.

See gh-27407
2021-09-21 13:04:29 +02:00
Sam Brannen b0dceb484a Remove Eclipse Web Tools Platform (WTP) configuration
Since the team no longer needs the ability to treat Eclipse projects as
WTP modules, this commit removes the obsolete custom WTP configuration
for importing projects into Eclipse IDE.

See gh-27407
2021-09-21 12:37:51 +02:00
Sam Brannen 65c1eac115 Fix formatting in Eclipse/STS Project Import Guide
See gh-27407
2021-09-21 12:16:06 +02:00
Sam Brannen a37dde9a1c Revise Eclipse/STS Project Import Guide based on status quo
See gh-27407
2021-09-21 12:11:27 +02:00
Sam Brannen 28496059bc Make TestNG test methods public due to bug in TestNG TestEngine
This commit makes all test methods in our TestNG test classes public
due to the following bug in the TestNG engine for the JUnit Platform.

https://github.com/junit-team/testng-engine/issues/16

See gh-27407
2021-09-21 10:35:34 +02:00
Sam Brannen 40c51efee8 Introduce @Suite for TestNG tests
In order to allow developers to execute TestNG tests in Eclipse IDE
without installing the TestNG plugin for Eclipse, this commit introduces
a JUnit Platform @Suite class that can be executed within the IDE.

See gh-27407
2021-09-21 10:33:25 +02:00
Sam Brannen e439d6f64d Upgrade to AssertJ 3.21.0 2021-09-20 14:54:25 +02:00
Marc Philipp e29867b96e Exclude TestCase classes in spring-test build
When not excluded, TestNG will pick up nested TestCase classes and run
them.

This commit therefore filters out `*TestCase` test classes from the
build since these are not intended to be executed with the build.

See gh-27406
2021-09-20 14:02:06 +02:00
Sam Brannen 0b552a3534 Migrate to TestNG Engine for the JUnit Platform in spring-test
Prior to this commit, we had configured separate test tasks for JUnit
and TestNG. In addition, we configured a standard `test` task that
depended on the `junit` and `testNG` tasks, and we had an additional
`aggregateTestReports` task that aggregated the reports from the JUnit
and TestNG test tasks.

Thanks to the introduction of the "TestNG Engine for the JUnit
Platform", this commit simplifies our Gradle build in the spring-test
module by running JUnit 4, JUnit Jupiter, and TestNG tests on the JUnit
Platform in a single Gradle `test` task.

See gh-27406
2021-09-20 14:02:06 +02:00
Brian Clozel a50537fbaf Polish "Fix collectionToDelimitedString failure for null elements."
Fixes gh-27419
2021-09-17 15:15:51 +02:00
Koy 0d6cc12274 Fix collectionToDelimitedString failure for null elements.
Prior to this commit, calling `StringUtils#collectionToDelimitedString`
would fail with an NPE if the collection contains null elements.

This commit ensures that null elements are converted as `"null"` in the
resulting String without failure.

See gh-27419
2021-09-17 15:15:26 +02:00
Sam Brannen 008aa48d5c Fix formatting for SQL IN clause example in ref docs
See gh-27388
2021-09-16 14:10:54 +02:00
Brian Clozel 00eef79e5c Upgrade to JApicmp Gradle Plugin 0.3.0
Fixes gh-27414
2021-09-15 14:40:42 +02:00
Brian Clozel 7907478d36 Watch 5.3.x branch in the CI pipeline
Main branch has moved to the 6.0.x line, so this commit updates this CI
pipeline to the new 5.3.x maintenance branch.
2021-09-15 12:17:07 +02:00
Spring Builds c7cca2e879 Next development version (v5.3.11-SNAPSHOT) 2021-09-15 07:24:10 +00:00
504 changed files with 3476 additions and 2116 deletions
+1 -1
View File
@@ -8,4 +8,4 @@ wiki page.
## Reporting a Vulnerability
Please see https://pivotal.io/security.
Please see https://spring.io/security-policy.
+36 -34
View File
@@ -1,17 +1,17 @@
plugins {
id 'io.spring.dependency-management' version '1.0.11.RELEASE' apply false
id 'io.spring.nohttp' version '0.0.10'
id 'org.jetbrains.kotlin.jvm' version '1.5.30' apply false
id "io.freefair.aspectj" version '6.2.0' apply false
id 'org.jetbrains.dokka' version '1.5.0' apply false
id 'org.jetbrains.kotlin.jvm' version '1.5.31' apply false
id "org.jetbrains.kotlin.plugin.serialization" version "1.5.31" apply false
id 'org.asciidoctor.jvm.convert' version '3.3.2'
id 'org.asciidoctor.jvm.pdf' version '3.3.2'
id 'de.undercouch.download' version '4.1.2'
id "io.freefair.aspectj" version '6.1.0' apply false
id "org.unbroken-dome.xjc" version '2.0.0' apply false
id "com.github.ben-manes.versions" version '0.39.0'
id "com.github.johnrengelman.shadow" version '7.0.0' apply false
id 'de.undercouch.download' version '4.1.2'
id "me.champeau.jmh" version "0.6.6" apply false
id "org.jetbrains.kotlin.plugin.serialization" version "1.5.30" apply false
id "org.unbroken-dome.xjc" version '2.0.0' apply false
}
ext {
@@ -28,15 +28,15 @@ configure(allprojects) { project ->
dependencyManagement {
imports {
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.5"
mavenBom "io.netty:netty-bom:4.1.68.Final"
mavenBom "io.projectreactor:reactor-bom:2020.0.11"
mavenBom "io.netty:netty-bom:4.1.70.Final"
mavenBom "io.projectreactor:reactor-bom:2020.0.13"
mavenBom "io.r2dbc:r2dbc-bom:Arabba-SR10"
mavenBom "io.rsocket:rsocket-bom:1.1.1"
mavenBom "org.eclipse.jetty:jetty-bom:9.4.43.v20210629"
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.30"
mavenBom "org.eclipse.jetty:jetty-bom:9.4.44.v20210927"
mavenBom "org.jetbrains.kotlin:kotlin-bom:1.5.31"
mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.5.2"
mavenBom "org.jetbrains.kotlinx:kotlinx-serialization-bom:1.2.2"
mavenBom "org.junit:junit-bom:5.8.0"
mavenBom "org.junit:junit-bom:5.8.1"
}
dependencies {
dependencySet(group: 'org.apache.logging.log4j', version: '2.14.1') {
@@ -45,7 +45,7 @@ configure(allprojects) { project ->
entry 'log4j-jul'
entry 'log4j-slf4j-impl'
}
dependency "org.slf4j:slf4j-api:1.7.30"
dependency "org.slf4j:slf4j-api:1.7.32"
dependency("com.google.code.findbugs:findbugs:3.0.1") {
exclude group: "dom4j", name: "dom4j"
}
@@ -56,7 +56,7 @@ configure(allprojects) { project ->
entry 'aspectjtools'
entry 'aspectjweaver'
}
dependencySet(group: 'org.codehaus.groovy', version: '3.0.8') {
dependencySet(group: 'org.codehaus.groovy', version: '3.0.9') {
entry 'groovy'
entry 'groovy-jsr223'
entry 'groovy-templates' // requires findbugs for warning-free compilation
@@ -68,8 +68,8 @@ configure(allprojects) { project ->
dependency "io.reactivex:rxjava-reactive-streams:1.2.1"
dependency "io.reactivex.rxjava2:rxjava:2.2.21"
dependency "io.reactivex.rxjava3:rxjava:3.1.1"
dependency "io.smallrye.reactive:mutiny:1.0.0"
dependency "io.projectreactor.tools:blockhound:1.0.4.RELEASE"
dependency "io.smallrye.reactive:mutiny:1.1.1"
dependency "io.projectreactor.tools:blockhound:1.0.6.RELEASE"
dependency "com.caucho:hessian:4.0.63"
dependency "com.fasterxml:aalto-xml:1.3.0"
@@ -77,13 +77,13 @@ configure(allprojects) { project ->
exclude group: "stax", name: "stax-api"
}
dependency "com.google.code.gson:gson:2.8.8"
dependency "com.google.protobuf:protobuf-java-util:3.17.3"
dependency "com.google.protobuf:protobuf-java-util:3.18.0"
dependency "com.googlecode.protobuf-java-format:protobuf-java-format:1.4"
dependency("com.thoughtworks.xstream:xstream:1.4.18") {
exclude group: "xpp3", name: "xpp3_min"
exclude group: "xmlpull", name: "xmlpull"
}
dependency "org.apache.johnzon:johnzon-jsonb:1.2.10"
dependency "org.apache.johnzon:johnzon-jsonb:1.2.14"
dependency("org.codehaus.jettison:jettison:1.3.8") {
exclude group: "stax", name: "stax-api"
}
@@ -95,11 +95,11 @@ configure(allprojects) { project ->
dependency "org.yaml:snakeyaml:1.29"
dependency "com.h2database:h2:1.4.200"
dependency "com.github.ben-manes.caffeine:caffeine:2.9.1"
dependency "com.github.ben-manes.caffeine:caffeine:2.9.2"
dependency "com.github.librepdf:openpdf:1.3.26"
dependency "com.rometools:rome:1.15.0"
dependency "com.rometools:rome:1.16.0"
dependency "commons-io:commons-io:2.5"
dependency "io.vavr:vavr:0.10.3"
dependency "io.vavr:vavr:0.10.4"
dependency "net.sf.jopt-simple:jopt-simple:5.0.4"
dependencySet(group: 'org.apache.activemq', version: '5.16.2') {
entry 'activemq-broker'
@@ -125,28 +125,28 @@ configure(allprojects) { project ->
dependency "org.ehcache:ehcache:3.4.0"
dependency "org.hibernate:hibernate-core:5.4.32.Final"
dependency "org.hibernate:hibernate-validator:6.2.0.Final"
dependency "org.webjars:webjars-locator-core:0.47"
dependency "org.webjars:webjars-locator-core:0.48"
dependency "org.webjars:underscorejs:1.8.3"
dependencySet(group: 'org.apache.tomcat', version: '9.0.52') {
dependencySet(group: 'org.apache.tomcat', version: '9.0.54') {
entry 'tomcat-util'
entry('tomcat-websocket') {
exclude group: "org.apache.tomcat", name: "tomcat-websocket-api"
exclude group: "org.apache.tomcat", name: "tomcat-servlet-api"
}
}
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.52') {
dependencySet(group: 'org.apache.tomcat.embed', version: '9.0.54') {
entry 'tomcat-embed-core'
entry 'tomcat-embed-websocket'
}
dependencySet(group: 'io.undertow', version: '2.2.10.Final') {
dependencySet(group: 'io.undertow', version: '2.2.12.Final') {
entry 'undertow-core'
entry('undertow-websockets-jsr') {
exclude group: "org.jboss.spec.javax.websocket", name: "jboss-websocket-api_1.1_spec"
}
entry('undertow-servlet') {
exclude group: "org.jboss.spec.javax.servlet", name: "jboss-servlet-api_3.1_spec"
exclude group: "org.jboss.spec.javax.annotation", name: "jboss-annotations-api_1.2_spec"
exclude group: "org.jboss.spec.javax.servlet", name: "jboss-servlet-api_4.0_spec"
exclude group: "org.jboss.spec.javax.annotation", name: "jboss-annotations-api_1.3_spec"
}
}
@@ -188,16 +188,17 @@ configure(allprojects) { project ->
exclude group: "junit", name: "junit"
}
dependency "org.testng:testng:7.4.0"
dependency "org.junit.support:testng-engine:1.0.1"
dependency "org.hamcrest:hamcrest:2.1"
dependency "org.awaitility:awaitility:3.1.6"
dependency "org.assertj:assertj-core:3.20.2"
dependencySet(group: 'org.xmlunit', version: '2.8.2') {
dependency "org.assertj:assertj-core:3.21.0"
dependencySet(group: 'org.xmlunit', version: '2.8.3') {
entry 'xmlunit-assertj'
entry('xmlunit-matchers') {
exclude group: "org.hamcrest", name: "hamcrest-core"
}
}
dependencySet(group: 'org.mockito', version: '3.12.4') {
dependencySet(group: 'org.mockito', version: '4.0.0') {
entry('mockito-core') {
exclude group: "org.hamcrest", name: "hamcrest-core"
}
@@ -205,10 +206,10 @@ configure(allprojects) { project ->
}
dependency "io.mockk:mockk:1.12.0"
dependency("net.sourceforge.htmlunit:htmlunit:2.52.0") {
dependency("net.sourceforge.htmlunit:htmlunit:2.54.0") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.seleniumhq.selenium:htmlunit-driver:2.52.0") {
dependency("org.seleniumhq.selenium:htmlunit-driver:2.54.0") {
exclude group: "commons-logging", name: "commons-logging"
}
dependency("org.seleniumhq.selenium:selenium-java:3.141.59") {
@@ -339,7 +340,7 @@ configure([rootProject] + javaProjects) { project ->
}
checkstyle {
toolVersion = "8.45.1"
toolVersion = "9.0"
configDirectory.set(rootProject.file("src/checkstyle"))
}
@@ -361,7 +362,7 @@ configure([rootProject] + javaProjects) { project ->
// JSR-305 only used for non-required meta-annotations
compileOnly("com.google.code.findbugs:jsr305")
testCompileOnly("com.google.code.findbugs:jsr305")
checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:0.0.15")
checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:0.0.29")
}
ext.javadocLinks = [
@@ -369,7 +370,6 @@ configure([rootProject] + javaProjects) { project ->
"https://docs.oracle.com/javaee/7/api/",
"https://docs.oracle.com/cd/E13222_01/wls/docs90/javadocs/", // CommonJ
"https://www.ibm.com/docs/api/v1/content/SSEQTP_8.5.5/com.ibm.websphere.javadoc.doc/web/apidocs/",
"https://glassfish.java.net/nonav/docs/v3/api/",
"https://docs.jboss.org/jbossas/javadoc/4.0.5/connector/",
"https://docs.jboss.org/jbossas/javadoc/7.1.2.Final/",
"https://tiles.apache.org/tiles-request/apidocs/",
@@ -383,7 +383,9 @@ configure([rootProject] + javaProjects) { project ->
"https://hc.apache.org/httpcomponents-client-5.1.x/current/httpclient5/apidocs/",
"https://projectreactor.io/docs/test/release/api/",
"https://junit.org/junit4/javadoc/4.13.2/",
"https://junit.org/junit5/docs/5.8.0/api/",
// Disabling linking to JUnit 5.8.1, since the `package-list` file no longer exists due to
// https://github.com/junit-team/junit5/commit/67ad4e545518b0ce2b0e7c96df31a669866d5003.
// "https://junit.org/junit5/docs/5.8.1/api/",
"https://www.reactive-streams.org/reactive-streams-1.0.3-javadoc/",
"https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/",
"https://r2dbc.io/spec/0.8.5.RELEASE/api/"
+1 -2
View File
@@ -8,8 +8,7 @@ repositories {
}
dependencies {
implementation "me.champeau.gradle:japicmp-gradle-plugin:0.2.8"
implementation "com.google.guava:guava:28.2-jre" // required by japicmp-gradle-plugin
implementation "me.champeau.gradle:japicmp-gradle-plugin:0.3.0"
}
gradlePlugin {
+1 -1
View File
@@ -5,7 +5,7 @@ github-repo: "https://github.com/spring-projects/spring-framework.git"
github-repo-name: "spring-projects/spring-framework"
docker-hub-organization: "springci"
artifactory-server: "https://repo.spring.io"
branch: "main"
branch: "5.3.x"
milestone: "5.3.x"
build-name: "spring-framework"
pipeline-name: "spring-framework"
+5
View File
@@ -46,6 +46,11 @@ resource_types:
source:
repository: springio/artifactory-resource
tag: 0.0.17
- name: github-release
type: registry-image
source:
repository: concourse/github-release-resource
tag: 1.5.5
- name: github-status-resource
type: registry-image
source:
+1 -1
View File
@@ -4,7 +4,7 @@ image_resource:
type: registry-image
source:
repository: springio/github-changelog-generator
tag: '0.0.6'
tag: '0.0.7'
inputs:
- name: git-repo
- name: artifactory-repo
+1 -1
View File
@@ -1,4 +1,4 @@
version=5.3.10-SNAPSHOT
version=5.3.13
org.gradle.jvmargs=-Xmx1536M
org.gradle.caching=true
org.gradle.parallel=true
+5 -5
View File
@@ -1,7 +1,7 @@
tasks.findByName("dokkaHtmlPartial")?.configure {
outputDirectory.set(new File(buildDir, "docs/kdoc"))
dokkaSourceSets {
configureEach {
outputDirectory.set(new File(buildDir, "docs/kdoc"))
dokkaSourceSets {
configureEach {
sourceRoots.setFrom(file("src/main/kotlin"))
classpath.from(sourceSets["main"].runtimeClasspath)
externalDocumentationLink {
@@ -17,7 +17,7 @@ tasks.findByName("dokkaHtmlPartial")?.configure {
url.set(new URL("https://kotlin.github.io/kotlinx.coroutines/"))
}
externalDocumentationLink {
url.set(new URL("https://hamcrest.org/JavaHamcrest/javadoc/2.1/"))
url.set(new URL("https://javadoc.io/doc/org.hamcrest/hamcrest/2.1/"))
}
externalDocumentationLink {
url.set(new URL("https://javadoc.io/doc/javax.servlet/javax.servlet-api/latest/"))
@@ -26,5 +26,5 @@ tasks.findByName("dokkaHtmlPartial")?.configure {
url.set(new URL("https://javadoc.io/static/io.rsocket/rsocket-core/1.1.1/"))
}
}
}
}
}
+3 -2
View File
@@ -46,8 +46,9 @@ task api(type: Javadoc) {
stylesheetFile = file("src/docs/api/stylesheet.css")
splitIndex = true
links(project.ext.javadocLinks)
addStringOption('Xdoclint:none', '-quiet')
if(JavaVersion.current().isJava9Compatible()) {
addBooleanOption('Xdoclint:syntax', true) // only check syntax with doclint
addBooleanOption('Xwerror', true) // fail build on Javadoc warnings
if (JavaVersion.current().isJava9Compatible()) {
addBooleanOption('html5', true)
}
}
+4 -26
View File
@@ -69,42 +69,20 @@ eclipse.classpath.file.whenMerged {
}
}
// Allow projects to be used as WTP modules
eclipse.project.natures 'org.eclipse.wst.common.project.facet.core.nature'
// Include project specific settings
task eclipseSettings(type: Copy) {
from rootProject.files(
'src/eclipse/org.eclipse.jdt.ui.prefs',
'src/eclipse/org.eclipse.wst.common.project.facet.core.xml')
'src/eclipse/org.eclipse.jdt.core.prefs',
'src/eclipse/org.eclipse.jdt.ui.prefs')
into project.file('.settings/')
outputs.upToDateWhen { false }
}
task eclipseJdtSettings(type: Copy) {
from rootProject.file('src/eclipse/org.eclipse.jdt.core.prefs')
into project.file('.settings/')
outputs.upToDateWhen { false }
}
task eclipseBuildship {
dependsOn eclipseSettings, eclipseJdtSettings
}
task eclipseWstComponentSettings(type: Copy) {
from rootProject.files('src/eclipse/org.eclipse.wst.common.component')
into project.file('.settings/')
expand(deployname: project.name)
outputs.upToDateWhen { false }
}
task cleanEclipseSettings(type: Delete) {
delete project.file('.settings/org.eclipse.jdt.core.prefs')
delete project.file('.settings/org.eclipse.jdt.ui.prefs')
delete project.file('.settings/org.eclipse.wst.common.component')
delete project.file('.settings/org.eclipse.wst.common.project.facet.core.xml')
}
tasks['eclipse'].dependsOn(eclipseSettings, eclipseJdtSettings, eclipseWstComponentSettings)
tasks['eclipseJdt'].dependsOn(eclipseJdtSettings)
tasks['eclipse'].dependsOn(eclipseSettings)
tasks['eclipseJdt'].dependsOn(eclipseSettings)
tasks['cleanEclipse'].dependsOn(cleanEclipseSettings)
+24 -20
View File
@@ -3,11 +3,11 @@
This document will guide you through the process of importing the Spring Framework
projects into Eclipse or the Spring Tool Suite (_STS_). It is recommended that you
have a recent version of Eclipse. As a bare minimum you will need Eclipse with full Java
8 support, Eclipse Buildship, the Kotlin plugin, and the Groovy plugin.
8 support, Eclipse Buildship, and the Groovy plugin.
The following instructions have been tested against [STS](https://spring.io/tools) 4.3.2
([download](https://github.com/spring-projects/sts4/wiki/Previous-Versions#spring-tools-432-changelog))
(based on Eclipse 4.12) with [Eclipse Buildship](https://projects.eclipse.org/projects/tools.buildship).
The following instructions have been tested against [STS](https://spring.io/tools) 4.12.0
([download](https://github.com/spring-projects/sts4/wiki/Previous-Versions#spring-tools-4120-changelog))
(based on Eclipse 4.21) with [Eclipse Buildship](https://projects.eclipse.org/projects/tools.buildship).
The instructions should work with the latest Eclipse distribution as long as you install
[Buildship](https://marketplace.eclipse.org/content/buildship-gradle-integration). Note
that STS 4 comes with Buildship preinstalled.
@@ -16,28 +16,32 @@ that STS 4 comes with Buildship preinstalled.
_When instructed to execute `./gradlew` from the command line, be sure to execute it within your locally cloned `spring-framework` working directory._
1. Ensure that Eclipse launches with JDK 8.
- For example, on Mac OS this can be configured in the `Info.plist` file located in the `Contents` folder of the installed Eclipse or STS application (e.g., the `Eclipse.app` file).
1. Install the [Kotlin Plugin for Eclipse](https://marketplace.eclipse.org/content/kotlin-plugin-eclipse) in Eclipse.
1. Install the [Eclipse Groovy Development Tools](https://github.com/groovy/groovy-eclipse/wiki) in Eclipse.
1. Switch to Groovy 2.5 (Preferences -> Groovy -> Compiler -> Switch to 2.5...) in Eclipse.
1. Change the _Forbidden reference (access rule)_ in Eclipse from Error to Warning
(Preferences -> Java -> Compiler -> Errors/Warnings -> Deprecated and restricted API -> Forbidden reference (access rule)).
1. Optionally install the [AspectJ Development Tools](https://marketplace.eclipse.org/content/aspectj-development-tools) (_AJDT_) if you need to work with the `spring-aspects` project. The AspectJ Development Tools available in the Eclipse Marketplace have been tested with these instructions using STS 4.5 (Eclipse 4.14).
1. Optionally install the [TestNG plugin](https://testng.org/doc/eclipse.html) in Eclipse if you need to execute TestNG tests in the `spring-test` module.
1. Install the [Groovy Development Tools](https://marketplace.eclipse.org/content/groovy-development-tools).
1. Switch to Groovy 3.0 in Eclipse (Preferences &#8594; Groovy &#8594; Compiler &#8594; Switch to 3.0...).
- If you encounter build errors stating something similar to _"Groovy: compiler mismatch: project level is 2.5, workspace level is 3.0"_, change the Groovy compiler version to 3.0 for each affected project.
1. Ensure that the _Forbidden reference (access rule)_ in Eclipse is set to `Info`
(Preferences &#8594; Java &#8594; Compiler &#8594; Errors/Warnings &#8594; Deprecated and restricted API &#8594; Forbidden reference (access rule)).
1. Optionally install the [Kotlin Plugin for Eclipse](https://marketplace.eclipse.org/content/kotlin-plugin-eclipse) if you need to execute Kotlin-based tests or develop Kotlin extensions.
- **NOTE**: As of September 21, 2021, it appears that the Kotlin Plugin for Eclipse does not yet work with Eclipse 4.21.
1. Optionally install the [AspectJ Development Tools](https://marketplace.eclipse.org/content/aspectj-development-tools) (_AJDT_) if you need to work with the `spring-aspects` project.
- **NOTE**: As of September 21, 2021, it appears that the AspectJ Development Tools do not yet work with Eclipse 4.21.
1. Optionally install the [TestNG plugin](https://testng.org/doc/eclipse.html) in Eclipse if you need to execute individual TestNG test classes or tests in the `spring-test` module.
- As an alternative to installing the TestNG plugin, you can execute the `org.springframework.test.context.testng.TestNGTestSuite` class as a "JUnit 5" test class in Eclipse.
1. Build `spring-oxm` from the command line with `./gradlew :spring-oxm:check`.
1. To apply project specific settings, run `./gradlew eclipseBuildship` from the command line.
1. Import into Eclipse (File -> Import -> Gradle -> Existing Gradle Project -> Navigate to the locally cloned `spring-framework` directory -> Select Finish).
1. To apply Spring Framework specific settings, run `./gradlew cleanEclipse eclipse` from the command line.
1. Import all projects into Eclipse (File &#8594; Import &#8594; Gradle &#8594; Existing Gradle Project &#8594; Navigate to the locally cloned `spring-framework` directory &#8594; Select Finish).
- If you have not installed AJDT, exclude the `spring-aspects` project from the import, if prompted, or close it after the import.
- If you run into errors during the import, you may need to set the _Java home_ for Gradle Buildship to the location of your JDK 8 installation in Eclipse (Preferences -> Gradle -> Java home).
1. If you need to execute JAXB-related tests in the `spring-oxm` project and wish to have the generated sources available, add the `build/generated-sources/jaxb` folder to the build path (right click on the `jaxb` folder and select `Build Path -> Use as Source Folder`).
- If you do not see the `build` folder in the `spring-oxm` project, ensure that the "Gradle build folder" is not filtered out from the view. This setting is available under "Filters" in the configuration of the Package Explorer (available by clicking on the small downward facing arrow in the upper right corner of the Package Explorer).
- If you run into errors during the import, you may need to set the _Java home_ for Gradle Buildship to the location of your JDK 8 installation in Eclipse (Preferences &#8594; Gradle &#8594; Java home).
1. If you need to execute JAXB-related tests in the `spring-oxm` project and wish to have the generated sources available, add the `build/generated-sources/jaxb` folder to the build path (right click on the `jaxb` folder and select "Build Path &#8594; Use as Source Folder").
- If you do not see the `build` folder in the `spring-oxm` project, ensure that the "Gradle build folder" is not filtered out from the view. This setting is available under "Filters" in the configuration of the Package Explorer (available by clicking on the _three vertical dots_ in the upper right corner of the Package Explorer).
1. Code away!
## Known Issues
1. `spring-core` and `spring-oxm` should be pre-compiled due to repackaged dependencies.
- See `*RepackJar` tasks in the build.
1. `spring-core` should be pre-compiled due to repackaged dependencies.
- See `*RepackJar` tasks in the `spring-core.gradle` build file.
1. `spring-oxm` should be pre-compiled due to JAXB types generated for tests.
- Note that executing `./gradlew :spring-oxm:check` as explained in the _Steps_ above will compile `spring-core` and generate JAXB types for `spring-oxm`.
1. `spring-aspects` does not compile due to references to aspect types unknown to Eclipse.
- If you installed _AJDT_ into Eclipse it should work.
1. While JUnit tests pass from the command line with Gradle, some may fail when run from
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 the original author 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,7 @@ class CglibAopProxy implements AopProxy, Serializable {
* validates it if not.
*/
private void validateClassIfNecessary(Class<?> proxySuperClass, @Nullable ClassLoader proxyClassLoader) {
if (logger.isWarnEnabled()) {
if (!this.advised.isOptimize() && logger.isInfoEnabled()) {
synchronized (validatedClasses) {
if (!validatedClasses.containsKey(proxySuperClass)) {
doValidateClass(proxySuperClass, proxyClassLoader,
@@ -679,13 +679,19 @@ class CglibAopProxy implements AopProxy, Serializable {
Object retVal;
// Check whether we only have one InvokerInterceptor: that is,
// no real advice, but just reflective invocation of the target.
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
if (chain.isEmpty() && CglibMethodInvocation.isMethodProxyCompatible(method)) {
// We can skip creating a MethodInvocation: just invoke the target directly.
// Note that the final invoker must be an InvokerInterceptor, so we know
// it does nothing but a reflective operation on the target, and no hot
// swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
try {
retVal = methodProxy.invoke(target, argsToUse);
}
catch (CodeGenerationException ex) {
CglibMethodInvocation.logFastClassGenerationFailure(method);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
}
else {
// We need to create a method invocation...
@@ -737,10 +743,7 @@ class CglibAopProxy implements AopProxy, Serializable {
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
// Only use method proxy for public methods not derived from java.lang.Object
this.methodProxy = (Modifier.isPublic(method.getModifiers()) &&
method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&
!AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method) ?
methodProxy : null);
this.methodProxy = (isMethodProxyCompatible(method) ? methodProxy : null);
}
@Override
@@ -776,10 +779,25 @@ class CglibAopProxy implements AopProxy, Serializable {
@Override
protected Object invokeJoinpoint() throws Throwable {
if (this.methodProxy != null) {
return this.methodProxy.invoke(this.target, this.arguments);
try {
return this.methodProxy.invoke(this.target, this.arguments);
}
catch (CodeGenerationException ex) {
logFastClassGenerationFailure(this.method);
}
}
else {
return super.invokeJoinpoint();
return super.invokeJoinpoint();
}
static boolean isMethodProxyCompatible(Method method) {
return (Modifier.isPublic(method.getModifiers()) &&
method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&
!AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method));
}
static void logFastClassGenerationFailure(Method method) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to generate CGLIB fast class for method: " + method);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -73,11 +73,9 @@ public class ProxyConfig implements Serializable {
* The exact meaning of "aggressive optimizations" will differ
* between proxies, but there is usually some tradeoff.
* Default is "false".
* <p>For example, optimization will usually mean that advice changes won't
* take effect after a proxy has been created. For this reason, optimization
* is disabled by default. An optimize value of "true" may be ignored
* if other settings preclude optimization: for example, if "exposeProxy"
* is set to "true" and that's not compatible with the optimization.
* <p>With Spring's current proxy options, this flag effectively
* enforces CGLIB proxies (similar to {@link #setProxyTargetClass})
* but without any class validation checks (for final methods etc).
*/
public void setOptimize(boolean optimize) {
this.optimize = optimize;
@@ -61,7 +61,7 @@ public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator {
* FactoryBean will get proxied. This default behavior applies as of Spring 2.0.
* If you intend to proxy a FactoryBean instance itself (a rare use case, but
* Spring 1.2's default behavior), specify the bean name of the FactoryBean
* including the factory-bean prefix "&": e.g. "&myFactoryBean".
* including the factory-bean prefix "&amp;": e.g. "&amp;myFactoryBean".
* @see org.springframework.beans.factory.FactoryBean
* @see org.springframework.beans.factory.BeanFactory#FACTORY_BEAN_PREFIX
*/
@@ -25,9 +25,11 @@ import org.springframework.lang.Nullable;
/**
* Convenient TargetSourceCreator using bean name prefixes to create one of three
* well-known TargetSource types:
* <li>: CommonsPool2TargetSource
* <li>% ThreadLocalTargetSource
* <li>! PrototypeTargetSource
* <ul>
* <li>: CommonsPool2TargetSource</li>
* <li>% ThreadLocalTargetSource</li>
* <li>! PrototypeTargetSource</li>
* </ul>
*
* @author Rod Johnson
* @author Stephane Nicoll
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -146,7 +146,7 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
@Override
public String toString() {
return getClass().getName() + ": class = " + this.clazz.getName() + "; methodName = " + methodName;
return getClass().getName() + ": class = " + this.clazz.getName() + "; methodName = " + this.methodName;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.support;
import org.junit.jupiter.api.Test;
@@ -29,10 +30,10 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Rob Harrop
* @author Rick Evans
*/
public class ClassUtilsTests {
class ClassUtilsTests {
@Test
public void getShortNameForCglibClass() {
void getShortNameForCglibClass() {
TestBean tb = new TestBean();
ProxyFactory pf = new ProxyFactory();
pf.setTarget(tb);
@@ -41,4 +42,5 @@ public class ClassUtilsTests {
String className = ClassUtils.getShortName(proxy.getClass());
assertThat(className).as("Class name did not match").isEqualTo("TestBean");
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,14 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.aspectj;
/**
* Marker interface for domain object that need DI through aspects.
* Marker interface for domain objects that need DI through aspects.
*
* @author Ramnivas Laddad
* @since 2.5
*/
public interface ConfigurableObject {
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,13 +22,18 @@ import org.springframework.contextsupport.testfixture.jcache.AbstractJCacheAnnot
/**
* @author Stephane Nicoll
* @author Sam Brannen
*/
public class JCacheAspectJNamespaceConfigTests extends AbstractJCacheAnnotationTests {
@Override
protected ApplicationContext getApplicationContext() {
return new GenericXmlApplicationContext(
"/org/springframework/cache/config/annotation-jcache-aspectj.xml");
GenericXmlApplicationContext context = new GenericXmlApplicationContext();
// Disallow bean definition overriding to test https://github.com/spring-projects/spring-framework/pull/27499
context.setAllowBeanDefinitionOverriding(false);
context.load("/org/springframework/cache/config/annotation-jcache-aspectj.xml");
context.refresh();
return context;
}
}
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.transaction.aspectj;
import org.springframework.transaction.annotation.Transactional;
@@ -29,4 +30,5 @@ public class ClassWithPrivateAnnotatedMember {
@Transactional
private void doInTransaction() {}
}
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.transaction.aspectj;
import org.springframework.transaction.annotation.Transactional;
@@ -29,4 +30,5 @@ public class ClassWithProtectedAnnotatedMember {
@Transactional
protected void doInTransaction() {}
}
@@ -100,9 +100,9 @@ public abstract class BeanUtils {
* @param clazz class to instantiate
* @return the new instance
* @throws BeanInstantiationException if the bean cannot be instantiated
* @see Class#newInstance()
* @deprecated as of Spring 5.0, following the deprecation of
* {@link Class#newInstance()} in JDK 9
* @see Class#newInstance()
*/
@Deprecated
public static <T> T instantiate(Class<T> clazz) throws BeanInstantiationException {
@@ -226,32 +226,45 @@ public abstract class BeanUtils {
}
/**
* Return a resolvable constructor for the provided class, either a primary constructor
* or single public constructor or simply a default constructor. Callers have to be
* prepared to resolve arguments for the returned constructor's parameters, if any.
* Return a resolvable constructor for the provided class, either a primary or single
* public constructor with arguments, or a single non-public constructor with arguments,
* or simply a default constructor. Callers have to be prepared to resolve arguments
* for the returned constructor's parameters, if any.
* @param clazz the class to check
* @throws IllegalStateException in case of no unique constructor found at all
* @since 5.3
* @see #findPrimaryConstructor
*/
@SuppressWarnings("unchecked")
public static <T> Constructor<T> getResolvableConstructor(Class<T> clazz) {
Constructor<T> ctor = findPrimaryConstructor(clazz);
if (ctor == null) {
Constructor<?>[] ctors = clazz.getConstructors();
if (ctor != null) {
return ctor;
}
Constructor<?>[] ctors = clazz.getConstructors();
if (ctors.length == 1) {
// A single public constructor
return (Constructor<T>) ctors[0];
}
else if (ctors.length == 0){
ctors = clazz.getDeclaredConstructors();
if (ctors.length == 1) {
ctor = (Constructor<T>) ctors[0];
}
else {
try {
ctor = clazz.getDeclaredConstructor();
}
catch (NoSuchMethodException ex) {
throw new IllegalStateException("No primary or single public constructor found for " +
clazz + " - and no default constructor found either");
}
// A single non-public constructor, e.g. from a non-public record type
return (Constructor<T>) ctors[0];
}
}
return ctor;
// Several constructors -> let's try to take the default constructor
try {
return clazz.getDeclaredConstructor();
}
catch (NoSuchMethodException ex) {
// Giving up...
}
// No unique constructor at all
throw new IllegalStateException("No primary or single unique constructor found for " + clazz);
}
/**
@@ -527,7 +540,7 @@ public abstract class BeanUtils {
/**
* Find a JavaBeans PropertyEditor following the 'Editor' suffix convention
* (e.g. "mypackage.MyDomainClass" -> "mypackage.MyDomainClassEditor").
* (e.g. "mypackage.MyDomainClass" &rarr; "mypackage.MyDomainClassEditor").
* <p>Compatible to the standard JavaBeans convention as implemented by
* {@link java.beans.PropertyEditorManager} but isolated from the latter's
* registered default editors for primitive types.
@@ -134,8 +134,8 @@ public abstract class PropertyAccessorUtils {
/**
* Determine the canonical name for the given property path.
* Removes surrounding quotes from map keys:<br>
* {@code map['key']} -> {@code map[key]}<br>
* {@code map["key"]} -> {@code map[key]}
* {@code map['key']} &rarr; {@code map[key]}<br>
* {@code map["key"]} &rarr; {@code map[key]}
* @param propertyName the bean property path
* @return the canonical representation of the property path
*/
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 the original author 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,10 +422,13 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
}
if (editor == null) {
// Find editor for superclass or interface.
for (Iterator<Class<?>> it = this.customEditors.keySet().iterator(); it.hasNext() && editor == null;) {
Class<?> key = it.next();
for (Map.Entry<Class<?>, PropertyEditor> entry : this.customEditors.entrySet()) {
if (editor != null) {
break;
}
Class<?> key = entry.getKey();
if (key.isAssignableFrom(requiredType)) {
editor = this.customEditors.get(key);
editor = entry.getValue();
// Cache editor for search type, to avoid the overhead
// of repeated assignable-from checks.
if (this.customEditorCache == null) {
@@ -459,7 +459,7 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
return metadata;
}
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
return InjectionMetadata.EMPTY;
}
@@ -539,8 +539,7 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
*/
@SuppressWarnings({"deprecation", "cast"})
protected boolean determineRequiredStatus(MergedAnnotation<?> ann) {
// The following (AnnotationAttributes) cast is required on JDK 9+.
return determineRequiredStatus((AnnotationAttributes)
return determineRequiredStatus(
ann.asMap(mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType())));
}
@@ -47,17 +47,17 @@ import org.springframework.util.ClassUtils;
* which uses this class to call a static initialization method:
*
* <pre class="code">
* &lt;bean id="myObject" class="org.springframework.beans.factory.config.MethodInvokingBean">
* &lt;property name="staticMethod" value="com.whatever.MyClass.init"/>
* &lt;/bean></pre>
* &lt;bean id="myObject" class="org.springframework.beans.factory.config.MethodInvokingBean"&gt;
* &lt;property name="staticMethod" value="com.whatever.MyClass.init"/&gt;
* &lt;/bean&gt;</pre>
*
* <p>An example of calling an instance method to start some server bean:
*
* <pre class="code">
* &lt;bean id="myStarter" class="org.springframework.beans.factory.config.MethodInvokingBean">
* &lt;property name="targetObject" ref="myServer"/>
* &lt;property name="targetMethod" value="start"/>
* &lt;/bean></pre>
* &lt;bean id="myStarter" class="org.springframework.beans.factory.config.MethodInvokingBean"&gt;
* &lt;property name="targetObject" ref="myServer"/&gt;
* &lt;property name="targetMethod" value="start"/&gt;
* &lt;/bean&gt;</pre>
*
* @author Juergen Hoeller
* @since 4.0.3
@@ -56,24 +56,24 @@ import org.springframework.lang.Nullable;
* which uses this class to call a static factory method:
*
* <pre class="code">
* &lt;bean id="myObject" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
* &lt;property name="staticMethod" value="com.whatever.MyClassFactory.getInstance"/>
* &lt;/bean></pre>
* &lt;bean id="myObject" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"&gt;
* &lt;property name="staticMethod" value="com.whatever.MyClassFactory.getInstance"/&gt;
* &lt;/bean&gt;</pre>
*
* <p>An example of calling a static method then an instance method to get at a
* Java system property. Somewhat verbose, but it works.
*
* <pre class="code">
* &lt;bean id="sysProps" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
* &lt;property name="targetClass" value="java.lang.System"/>
* &lt;property name="targetMethod" value="getProperties"/>
* &lt;/bean>
* &lt;bean id="sysProps" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"&gt;
* &lt;property name="targetClass" value="java.lang.System"/&gt;
* &lt;property name="targetMethod" value="getProperties"/&gt;
* &lt;/bean&gt;
*
* &lt;bean id="javaVersion" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
* &lt;property name="targetObject" ref="sysProps"/>
* &lt;property name="targetMethod" value="getProperty"/>
* &lt;property name="arguments" value="java.version"/>
* &lt;/bean></pre>
* &lt;bean id="javaVersion" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"&gt;
* &lt;property name="targetObject" ref="sysProps"/&gt;
* &lt;property name="targetMethod" value="getProperty"/&gt;
* &lt;property name="arguments" value="java.version"/&gt;
* &lt;/bean&gt;</pre>
*
* @author Colin Sampaleanu
* @author Juergen Hoeller
@@ -83,22 +83,22 @@ import org.springframework.util.StringUtils;
* <p>A sample config in an XML-based
* {@link org.springframework.beans.factory.BeanFactory} might look as follows:
*
* <pre class="code">&lt;beans>
* <pre class="code">&lt;beans&gt;
*
* &lt;!-- Prototype bean since we have state -->
* &lt;bean id="myService" class="a.b.c.MyService" singleton="false"/>
* &lt;!-- Prototype bean since we have state --&gt;
* &lt;bean id="myService" class="a.b.c.MyService" singleton="false"/&gt;
*
* &lt;!-- will lookup the above 'myService' bean by *TYPE* -->
* &lt;!-- will lookup the above 'myService' bean by *TYPE* --&gt;
* &lt;bean id="myServiceFactory"
* class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
* &lt;property name="serviceLocatorInterface" value="a.b.c.ServiceFactory"/>
* &lt;/bean>
* class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean"&gt;
* &lt;property name="serviceLocatorInterface" value="a.b.c.ServiceFactory"/&gt;
* &lt;/bean&gt;
*
* &lt;bean id="clientBean" class="a.b.c.MyClientBean">
* &lt;property name="myServiceFactory" ref="myServiceFactory"/>
* &lt;/bean>
* &lt;bean id="clientBean" class="a.b.c.MyClientBean"&gt;
* &lt;property name="myServiceFactory" ref="myServiceFactory"/&gt;
* &lt;/bean&gt;
*
*&lt;/beans></pre>
*&lt;/beans&gt;</pre>
*
* <p>The attendant {@code MyClientBean} class implementation might then
* look something like this:
@@ -135,22 +135,22 @@ import org.springframework.util.StringUtils;
* <p>A sample config in an XML-based
* {@link org.springframework.beans.factory.BeanFactory} might look as follows:
*
* <pre class="code">&lt;beans>
* <pre class="code">&lt;beans&gt;
*
* &lt;!-- Prototype beans since we have state (both extend MyService) -->
* &lt;bean id="specialService" class="a.b.c.SpecialService" singleton="false"/>
* &lt;bean id="anotherService" class="a.b.c.AnotherService" singleton="false"/>
* &lt;!-- Prototype beans since we have state (both extend MyService) --&gt;
* &lt;bean id="specialService" class="a.b.c.SpecialService" singleton="false"/&gt;
* &lt;bean id="anotherService" class="a.b.c.AnotherService" singleton="false"/&gt;
*
* &lt;bean id="myServiceFactory"
* class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
* &lt;property name="serviceLocatorInterface" value="a.b.c.ServiceFactory"/>
* &lt;/bean>
* class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean"&gt;
* &lt;property name="serviceLocatorInterface" value="a.b.c.ServiceFactory"/&gt;
* &lt;/bean&gt;
*
* &lt;bean id="clientBean" class="a.b.c.MyClientBean">
* &lt;property name="myServiceFactory" ref="myServiceFactory"/>
* &lt;/bean>
* &lt;bean id="clientBean" class="a.b.c.MyClientBean"&gt;
* &lt;property name="myServiceFactory" ref="myServiceFactory"/&gt;
* &lt;/bean&gt;
*
*&lt;/beans></pre>
*&lt;/beans&gt;</pre>
*
* <p>The attendant {@code MyClientBean} class implementation might then
* look something like this:
@@ -86,7 +86,7 @@ public abstract class YamlProcessor {
* </pre>
* when mapped with
* <pre class="code">
* setDocumentMatchers(properties ->
* setDocumentMatchers(properties -&gt;
* ("prod".equals(properties.getProperty("environment")) ? MatchStatus.FOUND : MatchStatus.NOT_FOUND));
* </pre>
* would end up as
@@ -75,18 +75,18 @@ import org.springframework.util.StringUtils;
*
* def reader = new GroovyBeanDefinitionReader(myApplicationContext)
* reader.beans {
* dataSource(BasicDataSource) { // <--- invokeMethod
* dataSource(BasicDataSource) { // &lt;--- invokeMethod
* driverClassName = "org.hsqldb.jdbcDriver"
* url = "jdbc:hsqldb:mem:grailsDB"
* username = "sa" // <-- setProperty
* username = "sa" // &lt;-- setProperty
* password = ""
* settings = [mynew:"setting"]
* }
* sessionFactory(SessionFactory) {
* dataSource = dataSource // <-- getProperty for retrieving references
* dataSource = dataSource // &lt;-- getProperty for retrieving references
* }
* myService(MyService) {
* nestedBean = { AnotherBean bean -> // <-- setProperty with closure for nested bean
* nestedBean = { AnotherBean bean -&gt; // &lt;-- setProperty with closure for nested bean
* dataSource = dataSource
* }
* }
@@ -113,7 +113,7 @@ import org.springframework.util.StringUtils;
* dataSource = dataSource
* }
* myService(MyService) {
* nestedBean = { AnotherBean bean ->
* nestedBean = { AnotherBean bean -&gt;
* dataSource = dataSource
* }
* }
@@ -1342,7 +1342,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param explicitArgs argument values passed in programmatically via the getBean method,
* or {@code null} if none (-> use constructor argument values from bean definition)
* or {@code null} if none (implying the use of constructor argument values from bean definition)
* @return a BeanWrapper for the new instance
* @see #getBean(String, Object[])
*/
@@ -1363,7 +1363,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @param mbd the bean definition for the bean
* @param ctors the chosen candidate constructors
* @param explicitArgs argument values passed in programmatically via the getBean method,
* or {@code null} if none (-> use constructor argument values from bean definition)
* or {@code null} if none (implying the use of constructor argument values from bean definition)
* @return a BeanWrapper for the new instance
*/
protected BeanWrapper autowireConstructor(
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -361,7 +361,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
else {
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
}
Scope scope = this.scopes.get(scopeName);
if (scope == null) {
@@ -61,6 +61,8 @@ import org.springframework.util.StringUtils;
@SuppressWarnings("serial")
class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
private static final String DESTROY_METHOD_NAME = "destroy";
private static final String CLOSE_METHOD_NAME = "close";
private static final String SHUTDOWN_METHOD_NAME = "shutdown";
@@ -72,12 +74,11 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
private final String beanName;
private final boolean invokeDisposableBean;
private final boolean nonPublicAccessAllowed;
@Nullable
private final AccessControlContext acc;
private final boolean invokeDisposableBean;
private boolean invokeAutoCloseable;
@Nullable
private String destroyMethodName;
@@ -88,6 +89,9 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
@Nullable
private final List<DestructionAwareBeanPostProcessor> beanPostProcessors;
@Nullable
private final AccessControlContext acc;
/**
* Create a new DisposableBeanAdapter for the given bean.
@@ -103,38 +107,45 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
Assert.notNull(bean, "Disposable bean must not be null");
this.bean = bean;
this.beanName = beanName;
this.invokeDisposableBean =
(this.bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod("destroy"));
this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
this.acc = acc;
this.invokeDisposableBean = (bean instanceof DisposableBean &&
!beanDefinition.isExternallyManagedDestroyMethod(DESTROY_METHOD_NAME));
String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
if (destroyMethodName != null &&
!(this.invokeDisposableBean && DESTROY_METHOD_NAME.equals(destroyMethodName)) &&
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
this.destroyMethodName = destroyMethodName;
Method destroyMethod = determineDestroyMethod(destroyMethodName);
if (destroyMethod == null) {
if (beanDefinition.isEnforceDestroyMethod()) {
throw new BeanDefinitionValidationException("Could not find a destroy method named '" +
destroyMethodName + "' on bean with name '" + beanName + "'");
}
}
else {
if (destroyMethod.getParameterCount() > 0) {
Class<?>[] paramTypes = destroyMethod.getParameterTypes();
if (paramTypes.length > 1) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has more than one parameter - not supported as destroy method");
}
else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has a non-boolean parameter - not supported as destroy method");
this.invokeAutoCloseable = (bean instanceof AutoCloseable && CLOSE_METHOD_NAME.equals(destroyMethodName));
if (!this.invokeAutoCloseable) {
this.destroyMethodName = destroyMethodName;
Method destroyMethod = determineDestroyMethod(destroyMethodName);
if (destroyMethod == null) {
if (beanDefinition.isEnforceDestroyMethod()) {
throw new BeanDefinitionValidationException("Could not find a destroy method named '" +
destroyMethodName + "' on bean with name '" + beanName + "'");
}
}
destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod);
else {
if (destroyMethod.getParameterCount() > 0) {
Class<?>[] paramTypes = destroyMethod.getParameterTypes();
if (paramTypes.length > 1) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has more than one parameter - not supported as destroy method");
}
else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has a non-boolean parameter - not supported as destroy method");
}
}
destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod);
}
this.destroyMethod = destroyMethod;
}
this.destroyMethod = destroyMethod;
}
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
this.acc = acc;
}
/**
@@ -149,26 +160,27 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
Assert.notNull(bean, "Disposable bean must not be null");
this.bean = bean;
this.beanName = bean.getClass().getName();
this.invokeDisposableBean = (this.bean instanceof DisposableBean);
this.nonPublicAccessAllowed = true;
this.acc = acc;
this.invokeDisposableBean = (this.bean instanceof DisposableBean);
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
this.acc = acc;
}
/**
* Create a new DisposableBeanAdapter for the given bean.
*/
private DisposableBeanAdapter(Object bean, String beanName, boolean invokeDisposableBean,
boolean nonPublicAccessAllowed, @Nullable String destroyMethodName,
private DisposableBeanAdapter(Object bean, String beanName, boolean nonPublicAccessAllowed,
boolean invokeDisposableBean, boolean invokeAutoCloseable, @Nullable String destroyMethodName,
@Nullable List<DestructionAwareBeanPostProcessor> postProcessors) {
this.bean = bean;
this.beanName = beanName;
this.invokeDisposableBean = invokeDisposableBean;
this.nonPublicAccessAllowed = nonPublicAccessAllowed;
this.acc = null;
this.invokeDisposableBean = invokeDisposableBean;
this.invokeAutoCloseable = invokeAutoCloseable;
this.destroyMethodName = destroyMethodName;
this.beanPostProcessors = postProcessors;
this.acc = null;
}
@@ -211,7 +223,32 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
}
}
if (this.destroyMethod != null) {
if (this.invokeAutoCloseable) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking close() on bean with name '" + this.beanName + "'");
}
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((AutoCloseable) this.bean).close();
return null;
}, this.acc);
}
else {
((AutoCloseable) this.bean).close();
}
}
catch (Throwable ex) {
String msg = "Invocation of close method failed on bean with name '" + this.beanName + "'";
if (logger.isDebugEnabled()) {
logger.warn(msg, ex);
}
else {
logger.warn(msg + ": " + ex);
}
}
}
else if (this.destroyMethod != null) {
invokeCustomDestroyMethod(this.destroyMethod);
}
else if (this.destroyMethodName != null) {
@@ -259,7 +296,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
args[0] = Boolean.TRUE;
}
if (logger.isTraceEnabled()) {
logger.trace("Invoking destroy method '" + this.destroyMethodName +
logger.trace("Invoking custom destroy method '" + this.destroyMethodName +
"' on bean with name '" + this.beanName + "'");
}
try {
@@ -282,7 +319,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
}
}
catch (InvocationTargetException ex) {
String msg = "Destroy method '" + this.destroyMethodName + "' on bean with name '" +
String msg = "Custom destroy method '" + this.destroyMethodName + "' on bean with name '" +
this.beanName + "' threw an exception";
if (logger.isDebugEnabled()) {
logger.warn(msg, ex.getTargetException());
@@ -292,7 +329,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
}
}
catch (Throwable ex) {
logger.warn("Failed to invoke destroy method '" + this.destroyMethodName +
logger.warn("Failed to invoke custom destroy method '" + this.destroyMethodName +
"' on bean with name '" + this.beanName + "'", ex);
}
}
@@ -312,8 +349,9 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
}
}
}
return new DisposableBeanAdapter(this.bean, this.beanName, this.invokeDisposableBean,
this.nonPublicAccessAllowed, this.destroyMethodName, serializablePostProcessors);
return new DisposableBeanAdapter(
this.bean, this.beanName, this.nonPublicAccessAllowed, this.invokeDisposableBean,
this.invokeAutoCloseable, this.destroyMethodName, serializablePostProcessors);
}
@@ -323,10 +361,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
* @param beanDefinition the corresponding bean definition
*/
public static boolean hasDestroyMethod(Object bean, RootBeanDefinition beanDefinition) {
if (bean instanceof DisposableBean || bean instanceof AutoCloseable) {
return true;
}
return inferDestroyMethodIfNecessary(bean, beanDefinition) != null;
return (bean instanceof DisposableBean || inferDestroyMethodIfNecessary(bean, beanDefinition) != null);
}
@@ -348,21 +383,27 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
String destroyMethodName = beanDefinition.resolvedDestroyMethodName;
if (destroyMethodName == null) {
destroyMethodName = beanDefinition.getDestroyMethodName();
boolean autoCloseable = (bean instanceof AutoCloseable);
if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName) ||
(destroyMethodName == null && bean instanceof AutoCloseable)) {
// Only perform destroy method inference or Closeable detection
// in case of the bean not explicitly implementing DisposableBean
(destroyMethodName == null && autoCloseable)) {
// Only perform destroy method inference in case of the bean
// not explicitly implementing the DisposableBean interface
destroyMethodName = null;
if (!(bean instanceof DisposableBean)) {
try {
destroyMethodName = bean.getClass().getMethod(CLOSE_METHOD_NAME).getName();
if (autoCloseable) {
destroyMethodName = CLOSE_METHOD_NAME;
}
catch (NoSuchMethodException ex) {
else {
try {
destroyMethodName = bean.getClass().getMethod(SHUTDOWN_METHOD_NAME).getName();
destroyMethodName = bean.getClass().getMethod(CLOSE_METHOD_NAME).getName();
}
catch (NoSuchMethodException ex2) {
// no candidate destroy method found
catch (NoSuchMethodException ex) {
try {
destroyMethodName = bean.getClass().getMethod(SHUTDOWN_METHOD_NAME).getName();
}
catch (NoSuchMethodException ex2) {
// no candidate destroy method found
}
}
}
}
@@ -21,7 +21,8 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.function.Supplier;
@@ -422,15 +423,21 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
return this.factoryMethodToIntrospect;
}
/**
* Register an externally managed configuration method or field.
*/
public void registerExternallyManagedConfigMember(Member configMember) {
synchronized (this.postProcessingLock) {
if (this.externallyManagedConfigMembers == null) {
this.externallyManagedConfigMembers = new HashSet<>(1);
this.externallyManagedConfigMembers = new LinkedHashSet<>(1);
}
this.externallyManagedConfigMembers.add(configMember);
}
}
/**
* Check whether the given method or field is an externally managed configuration member.
*/
public boolean isExternallyManagedConfigMember(Member configMember) {
synchronized (this.postProcessingLock) {
return (this.externallyManagedConfigMembers != null &&
@@ -438,15 +445,33 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
}
}
/**
* Return all externally managed configuration methods and fields (as an immutable Set).
* @since 5.3.11
*/
public Set<Member> getExternallyManagedConfigMembers() {
synchronized (this.postProcessingLock) {
return (this.externallyManagedConfigMembers != null ?
Collections.unmodifiableSet(new LinkedHashSet<>(this.externallyManagedConfigMembers)) :
Collections.emptySet());
}
}
/**
* Register an externally managed configuration initialization method.
*/
public void registerExternallyManagedInitMethod(String initMethod) {
synchronized (this.postProcessingLock) {
if (this.externallyManagedInitMethods == null) {
this.externallyManagedInitMethods = new HashSet<>(1);
this.externallyManagedInitMethods = new LinkedHashSet<>(1);
}
this.externallyManagedInitMethods.add(initMethod);
}
}
/**
* Check whether the given method name indicates an externally managed initialization method.
*/
public boolean isExternallyManagedInitMethod(String initMethod) {
synchronized (this.postProcessingLock) {
return (this.externallyManagedInitMethods != null &&
@@ -454,15 +479,33 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
}
}
/**
* Return all externally managed initialization methods (as an immutable Set).
* @since 5.3.11
*/
public Set<String> getExternallyManagedInitMethods() {
synchronized (this.postProcessingLock) {
return (this.externallyManagedInitMethods != null ?
Collections.unmodifiableSet(new LinkedHashSet<>(this.externallyManagedInitMethods)) :
Collections.emptySet());
}
}
/**
* Register an externally managed configuration destruction method.
*/
public void registerExternallyManagedDestroyMethod(String destroyMethod) {
synchronized (this.postProcessingLock) {
if (this.externallyManagedDestroyMethods == null) {
this.externallyManagedDestroyMethods = new HashSet<>(1);
this.externallyManagedDestroyMethods = new LinkedHashSet<>(1);
}
this.externallyManagedDestroyMethods.add(destroyMethod);
}
}
/**
* Check whether the given method name indicates an externally managed destruction method.
*/
public boolean isExternallyManagedDestroyMethod(String destroyMethod) {
synchronized (this.postProcessingLock) {
return (this.externallyManagedDestroyMethods != null &&
@@ -470,6 +513,18 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
}
}
/**
* Return all externally managed destruction methods (as an immutable Set).
* @since 5.3.11
*/
public Set<String> getExternallyManagedDestroyMethods() {
synchronized (this.postProcessingLock) {
return (this.externallyManagedDestroyMethods != null ?
Collections.unmodifiableSet(new LinkedHashSet<>(this.externallyManagedDestroyMethods)) :
Collections.emptySet());
}
}
@Override
public RootBeanDefinition cloneBeanDefinition() {
@@ -39,7 +39,7 @@ import org.springframework.util.xml.XmlValidationModeDetector;
* when starting your JVM. For example, to use the Oracle {@link DocumentBuilder},
* you might start your application like as follows:
*
* <pre code="class">java -Djavax.xml.parsers.DocumentBuilderFactory=oracle.xml.jaxp.JXDocumentBuilderFactory MyMainClass</pre>
* <pre class="code">java -Djavax.xml.parsers.DocumentBuilderFactory=oracle.xml.jaxp.JXDocumentBuilderFactory MyMainClass</pre>
*
* @author Rob Harrop
* @author Juergen Hoeller
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -64,24 +64,24 @@ public final class ParserContext {
}
public final XmlReaderContext getReaderContext() {
public XmlReaderContext getReaderContext() {
return this.readerContext;
}
public final BeanDefinitionRegistry getRegistry() {
public BeanDefinitionRegistry getRegistry() {
return this.readerContext.getRegistry();
}
public final BeanDefinitionParserDelegate getDelegate() {
public BeanDefinitionParserDelegate getDelegate() {
return this.delegate;
}
@Nullable
public final BeanDefinition getContainingBeanDefinition() {
public BeanDefinition getContainingBeanDefinition() {
return this.containingBeanDefinition;
}
public final boolean isNested() {
public boolean isNested() {
return (this.containingBeanDefinition != null);
}
@@ -71,13 +71,13 @@ public class PluggableSchemaResolver implements EntityResolver {
private final String schemaMappingsLocation;
/** Stores the mapping of schema URL -> local schema path. */
/** Stores the mapping of schema URL &rarr; local schema path. */
@Nullable
private volatile Map<String, String> schemaMappings;
/**
* Loads the schema URL -> schema file location mappings using the default
* Loads the schema URL &rarr; schema file location mappings using the default
* mapping file pattern "META-INF/spring.schemas".
* @param classLoader the ClassLoader to use for loading
* (can be {@code null}) to use the default ClassLoader)
@@ -89,7 +89,7 @@ public class PluggableSchemaResolver implements EntityResolver {
}
/**
* Loads the schema URL -> schema file location mappings using the given
* Loads the schema URL &rarr; schema file location mappings using the given
* mapping file pattern.
* @param classLoader the ClassLoader to use for loading
* (can be {@code null}) to use the default ClassLoader)
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.support.security.support;
/**
@@ -27,4 +28,5 @@ public class CustomCallbackBean {
public void destroy() {
System.setProperty("security.destroy", "true");
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.support.security.support;
import org.springframework.beans.factory.DisposableBean;
@@ -26,4 +27,5 @@ public class DestroyBean implements DisposableBean {
public void destroy() throws Exception {
System.setProperty("security.destroy", "true");
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.support.security.support;
/**
@@ -33,4 +34,5 @@ public class FactoryBean {
System.getProperties();
return new Object();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.support.security.support;
import org.springframework.beans.factory.InitializingBean;
@@ -26,4 +27,5 @@ public class InitBean implements InitializingBean {
public void afterPropertiesSet() throws Exception {
System.getProperties();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.support.security.support;
/**
@@ -27,4 +28,5 @@ public class PropertyBean {
public void setProperty(Object property) {
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.testfixture.beans;
/**
@@ -65,4 +66,5 @@ public class DummyBean {
public TestBean getSpouse() {
return spouse;
}
}
@@ -896,7 +896,7 @@ public class MimeMessageHelper {
* <p><b>NOTE:</b> Invoke {@code addInline} <i>after</i> {@link #setText};
* else, mail readers might not be able to resolve inline references correctly.
* @param contentId the content ID to use. Will end up as "Content-ID" header
* in the body part, surrounded by angle brackets: e.g. "myId" -> "&lt;myId&gt;".
* in the body part, surrounded by angle brackets: e.g. "myId" &rarr; "&lt;myId&gt;".
* Can be referenced in HTML source via src="cid:myId" expressions.
* @param dataSource the {@code javax.activation.DataSource} to take
* the content from, determining the InputStream and the content type
@@ -923,7 +923,7 @@ public class MimeMessageHelper {
* <p><b>NOTE:</b> Invoke {@code addInline} <i>after</i> {@link #setText};
* else, mail readers might not be able to resolve inline references correctly.
* @param contentId the content ID to use. Will end up as "Content-ID" header
* in the body part, surrounded by angle brackets: e.g. "myId" -> "&lt;myId&gt;".
* in the body part, surrounded by angle brackets: e.g. "myId" &rarr; "&lt;myId&gt;".
* Can be referenced in HTML source via src="cid:myId" expressions.
* @param file the File resource to take the content from
* @throws MessagingException in case of errors
@@ -950,7 +950,7 @@ public class MimeMessageHelper {
* <p><b>NOTE:</b> Invoke {@code addInline} <i>after</i> {@link #setText};
* else, mail readers might not be able to resolve inline references correctly.
* @param contentId the content ID to use. Will end up as "Content-ID" header
* in the body part, surrounded by angle brackets: e.g. "myId" -> "&lt;myId&gt;".
* in the body part, surrounded by angle brackets: e.g. "myId" &rarr; "&lt;myId&gt;".
* Can be referenced in HTML source via src="cid:myId" expressions.
* @param resource the resource to take the content from
* @throws MessagingException in case of errors
@@ -976,7 +976,7 @@ public class MimeMessageHelper {
* <p><b>NOTE:</b> Invoke {@code addInline} <i>after</i> {@code setText};
* else, mail readers might not be able to resolve inline references correctly.
* @param contentId the content ID to use. Will end up as "Content-ID" header
* in the body part, surrounded by angle brackets: e.g. "myId" -> "&lt;myId&gt;".
* in the body part, surrounded by angle brackets: e.g. "myId" &rarr; "&lt;myId&gt;".
* Can be referenced in HTML source via src="cid:myId" expressions.
* @param inputStreamSource the resource to take the content from
* @param contentType the content type to use for the element
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -570,7 +570,7 @@ public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBe
CollectionUtils.mergePropertiesIntoMap(this.quartzProperties, mergedProps);
if (this.dataSource != null) {
mergedProps.setProperty(StdSchedulerFactory.PROP_JOB_STORE_CLASS, LocalDataSourceJobStore.class.getName());
mergedProps.putIfAbsent(StdSchedulerFactory.PROP_JOB_STORE_CLASS, LocalDataSourceJobStore.class.getName());
}
// Determine scheduler name across local settings and Quartz properties...
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ package org.springframework.scheduling.quartz;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.sql.DataSource;
@@ -30,6 +31,7 @@ import org.quartz.SchedulerContext;
import org.quartz.SchedulerFactory;
import org.quartz.impl.JobDetailImpl;
import org.quartz.impl.SchedulerRepository;
import org.quartz.impl.jdbcjobstore.JobStoreTX;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
@@ -40,6 +42,8 @@ import org.springframework.context.support.StaticApplicationContext;
import org.springframework.core.task.TaskExecutor;
import org.springframework.core.testfixture.EnabledForTestGroups;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
@@ -57,10 +61,10 @@ import static org.springframework.core.testfixture.TestGroup.LONG_RUNNING;
* @author Sam Brannen
* @since 20.02.2004
*/
public class QuartzSupportTests {
class QuartzSupportTests {
@Test
public void schedulerFactoryBeanWithApplicationContext() throws Exception {
void schedulerFactoryBeanWithApplicationContext() throws Exception {
TestBean tb = new TestBean("tb", 99);
StaticApplicationContext ac = new StaticApplicationContext();
@@ -97,7 +101,7 @@ public class QuartzSupportTests {
@Test
@EnabledForTestGroups(LONG_RUNNING)
public void schedulerWithTaskExecutor() throws Exception {
void schedulerWithTaskExecutor() throws Exception {
CountingTaskExecutor taskExecutor = new CountingTaskExecutor();
DummyJob.count = 0;
@@ -130,7 +134,7 @@ public class QuartzSupportTests {
@Test
@SuppressWarnings({ "unchecked", "rawtypes" })
public void jobDetailWithRunnableInsteadOfJob() {
void jobDetailWithRunnableInsteadOfJob() {
JobDetailImpl jobDetail = new JobDetailImpl();
assertThatIllegalArgumentException().isThrownBy(() ->
jobDetail.setJobClass((Class) DummyRunnable.class));
@@ -138,7 +142,7 @@ public class QuartzSupportTests {
@Test
@EnabledForTestGroups(LONG_RUNNING)
public void schedulerWithQuartzJobBean() throws Exception {
void schedulerWithQuartzJobBean() throws Exception {
DummyJob.param = 0;
DummyJob.count = 0;
@@ -171,7 +175,7 @@ public class QuartzSupportTests {
@Test
@EnabledForTestGroups(LONG_RUNNING)
public void schedulerWithSpringBeanJobFactory() throws Exception {
void schedulerWithSpringBeanJobFactory() throws Exception {
DummyJob.param = 0;
DummyJob.count = 0;
@@ -206,7 +210,7 @@ public class QuartzSupportTests {
@Test
@EnabledForTestGroups(LONG_RUNNING)
public void schedulerWithSpringBeanJobFactoryAndParamMismatchNotIgnored() throws Exception {
void schedulerWithSpringBeanJobFactoryAndParamMismatchNotIgnored() throws Exception {
DummyJob.param = 0;
DummyJob.count = 0;
@@ -242,7 +246,7 @@ public class QuartzSupportTests {
@Test
@EnabledForTestGroups(LONG_RUNNING)
public void schedulerWithSpringBeanJobFactoryAndQuartzJobBean() throws Exception {
void schedulerWithSpringBeanJobFactoryAndQuartzJobBean() throws Exception {
DummyJobBean.param = 0;
DummyJobBean.count = 0;
@@ -276,7 +280,7 @@ public class QuartzSupportTests {
@Test
@EnabledForTestGroups(LONG_RUNNING)
public void schedulerWithSpringBeanJobFactoryAndJobSchedulingData() throws Exception {
void schedulerWithSpringBeanJobFactoryAndJobSchedulingData() throws Exception {
DummyJob.param = 0;
DummyJob.count = 0;
@@ -294,7 +298,7 @@ public class QuartzSupportTests {
}
@Test // SPR-772
public void multipleSchedulers() throws Exception {
void multipleSchedulers() throws Exception {
try (ClassPathXmlApplicationContext ctx = context("multipleSchedulers.xml")) {
Scheduler scheduler1 = (Scheduler) ctx.getBean("scheduler1");
Scheduler scheduler2 = (Scheduler) ctx.getBean("scheduler2");
@@ -305,7 +309,7 @@ public class QuartzSupportTests {
}
@Test // SPR-16884
public void multipleSchedulersWithQuartzProperties() throws Exception {
void multipleSchedulersWithQuartzProperties() throws Exception {
try (ClassPathXmlApplicationContext ctx = context("multipleSchedulersWithQuartzProperties.xml")) {
Scheduler scheduler1 = (Scheduler) ctx.getBean("scheduler1");
Scheduler scheduler2 = (Scheduler) ctx.getBean("scheduler2");
@@ -317,12 +321,13 @@ public class QuartzSupportTests {
@Test
@EnabledForTestGroups(LONG_RUNNING)
public void twoAnonymousMethodInvokingJobDetailFactoryBeans() throws Exception {
Thread.sleep(3000);
void twoAnonymousMethodInvokingJobDetailFactoryBeans() throws Exception {
try (ClassPathXmlApplicationContext ctx = context("multipleAnonymousMethodInvokingJobDetailFB.xml")) {
QuartzTestBean exportService = (QuartzTestBean) ctx.getBean("exportService");
QuartzTestBean importService = (QuartzTestBean) ctx.getBean("importService");
Thread.sleep(400);
assertThat(exportService.getImportCount()).as("doImport called exportService").isEqualTo(0);
assertThat(exportService.getExportCount()).as("doExport not called on exportService").isEqualTo(2);
assertThat(importService.getImportCount()).as("doImport not called on importService").isEqualTo(2);
@@ -332,12 +337,13 @@ public class QuartzSupportTests {
@Test
@EnabledForTestGroups(LONG_RUNNING)
public void schedulerAccessorBean() throws Exception {
Thread.sleep(3000);
void schedulerAccessorBean() throws Exception {
try (ClassPathXmlApplicationContext ctx = context("schedulerAccessorBean.xml")) {
QuartzTestBean exportService = (QuartzTestBean) ctx.getBean("exportService");
QuartzTestBean importService = (QuartzTestBean) ctx.getBean("importService");
Thread.sleep(400);
assertThat(exportService.getImportCount()).as("doImport called exportService").isEqualTo(0);
assertThat(exportService.getExportCount()).as("doExport not called on exportService").isEqualTo(2);
assertThat(importService.getImportCount()).as("doImport not called on importService").isEqualTo(2);
@@ -347,7 +353,7 @@ public class QuartzSupportTests {
@Test
@SuppressWarnings("resource")
public void schedulerAutoStartsOnContextRefreshedEventByDefault() throws Exception {
void schedulerAutoStartsOnContextRefreshedEventByDefault() throws Exception {
StaticApplicationContext context = new StaticApplicationContext();
context.registerBeanDefinition("scheduler", new RootBeanDefinition(SchedulerFactoryBean.class));
Scheduler bean = context.getBean("scheduler", Scheduler.class);
@@ -358,7 +364,7 @@ public class QuartzSupportTests {
@Test
@SuppressWarnings("resource")
public void schedulerAutoStartupFalse() throws Exception {
void schedulerAutoStartupFalse() throws Exception {
StaticApplicationContext context = new StaticApplicationContext();
BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(SchedulerFactoryBean.class)
.addPropertyValue("autoStartup", false).getBeanDefinition();
@@ -370,7 +376,7 @@ public class QuartzSupportTests {
}
@Test
public void schedulerRepositoryExposure() throws Exception {
void schedulerRepositoryExposure() throws Exception {
try (ClassPathXmlApplicationContext ctx = context("schedulerRepositoryExposure.xml")) {
assertThat(ctx.getBean("scheduler")).isSameAs(SchedulerRepository.getInstance().lookup("myScheduler"));
}
@@ -381,7 +387,7 @@ public class QuartzSupportTests {
* TODO: Against Quartz 2.2, this test's job doesn't actually execute anymore...
*/
@Test
public void schedulerWithHsqlDataSource() throws Exception {
void schedulerWithHsqlDataSource() throws Exception {
DummyJob.param = 0;
DummyJob.count = 0;
@@ -396,12 +402,36 @@ public class QuartzSupportTests {
}
}
@Test
@SuppressWarnings("resource")
void schedulerFactoryBeanWithCustomJobStore() throws Exception {
StaticApplicationContext context = new StaticApplicationContext();
String dbName = "mydb";
EmbeddedDatabase database = new EmbeddedDatabaseBuilder().setName(dbName).build();
Properties properties = new Properties();
properties.setProperty("org.quartz.jobStore.class", JobStoreTX.class.getName());
properties.setProperty("org.quartz.jobStore.dataSource", dbName);
BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(SchedulerFactoryBean.class)
.addPropertyValue("autoStartup", false)
.addPropertyValue("dataSource", database)
.addPropertyValue("quartzProperties", properties)
.getBeanDefinition();
context.registerBeanDefinition("scheduler", beanDefinition);
Scheduler scheduler = context.getBean(Scheduler.class);
assertThat(scheduler.getMetaData().getJobStoreClass()).isEqualTo(JobStoreTX.class);
}
private ClassPathXmlApplicationContext context(String path) {
return new ClassPathXmlApplicationContext(path, getClass());
}
public static class CountingTaskExecutor implements TaskExecutor {
private static class CountingTaskExecutor implements TaskExecutor {
private int count;
@@ -413,12 +443,14 @@ public class QuartzSupportTests {
}
public static class DummyJob implements Job {
private static class DummyJob implements Job {
private static int param;
private static int count;
@SuppressWarnings("unused")
// Must be public
public void setParam(int value) {
if (param > 0) {
throw new IllegalStateException("Param already set");
@@ -433,12 +465,13 @@ public class QuartzSupportTests {
}
public static class DummyJobBean extends QuartzJobBean {
private static class DummyJobBean extends QuartzJobBean {
private static int param;
private static int count;
@SuppressWarnings("unused")
public void setParam(int value) {
if (param > 0) {
throw new IllegalStateException("Param already set");
@@ -453,7 +486,7 @@ public class QuartzSupportTests {
}
public static class DummyRunnable implements Runnable {
private static class DummyRunnable implements Runnable {
@Override
public void run() {
@@ -19,7 +19,7 @@
<property name="targetMethod" value="doExport"/>
</bean>
</property>
<property name="repeatInterval" value="1000"/>
<property name="repeatInterval" value="200"/>
<property name="repeatCount" value="1"/>
</bean>
@@ -30,7 +30,7 @@
<property name="targetMethod" value="doImport"/>
</bean>
</property>
<property name="repeatInterval" value="1000"/>
<property name="repeatInterval" value="200"/>
<property name="repeatCount" value="1"/>
</bean>
@@ -21,7 +21,7 @@
<property name="targetMethod" value="doExport"/>
</bean>
</property>
<property name="repeatInterval" value="1000"/>
<property name="repeatInterval" value="200"/>
<property name="repeatCount" value="1"/>
</bean>
@@ -32,7 +32,7 @@
<property name="targetMethod" value="doImport"/>
</bean>
</property>
<property name="repeatInterval" value="1000"/>
<property name="repeatInterval" value="200"/>
<property name="repeatCount" value="1"/>
</bean>
+1 -1
View File
@@ -34,8 +34,8 @@ dependencies {
testImplementation("org.codehaus.groovy:groovy-test")
testImplementation("org.codehaus.groovy:groovy-xml")
testImplementation("org.apache.commons:commons-pool2")
testImplementation("javax.inject:javax.inject-tck")
testImplementation("org.awaitility:awaitility")
testImplementation("javax.inject:javax.inject-tck")
testRuntimeOnly("javax.xml.bind:jaxb-api")
testRuntimeOnly("org.glassfish:javax.el")
// Substitute for javax.management:jmxremote_optional:1.0.1_04 (not available on Maven Central)
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -244,17 +244,21 @@ class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser
private static void registerCacheAspect(Element element, ParserContext parserContext) {
if (!parserContext.getRegistry().containsBeanDefinition(CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME)) {
Object eleSource = parserContext.extractSource(element);
RootBeanDefinition def = new RootBeanDefinition();
def.setBeanClassName(JCACHE_ASPECT_CLASS_NAME);
def.setFactoryMethodName("aspectOf");
BeanDefinition sourceDef = createJCacheOperationSourceBeanDefinition(element, eleSource);
String sourceName =
parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
def.getPropertyValues().add("cacheOperationSource", new RuntimeBeanReference(sourceName));
Object source = parserContext.extractSource(element);
parserContext.registerBeanComponent(new BeanComponentDefinition(sourceDef, sourceName));
parserContext.registerBeanComponent(new BeanComponentDefinition(def, CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME));
BeanDefinition cacheOperationSourceDef = createJCacheOperationSourceBeanDefinition(element, source);
String cacheOperationSourceName = parserContext.getReaderContext().registerWithGeneratedName(cacheOperationSourceDef);
RootBeanDefinition jcacheAspectDef = new RootBeanDefinition();
jcacheAspectDef.setBeanClassName(JCACHE_ASPECT_CLASS_NAME);
jcacheAspectDef.setFactoryMethodName("aspectOf");
jcacheAspectDef.getPropertyValues().add("cacheOperationSource", new RuntimeBeanReference(cacheOperationSourceName));
parserContext.getRegistry().registerBeanDefinition(CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME, jcacheAspectDef);
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source);
compositeDef.addNestedComponent(new BeanComponentDefinition(cacheOperationSourceDef, cacheOperationSourceName));
compositeDef.addNestedComponent(new BeanComponentDefinition(jcacheAspectDef, CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME));
parserContext.registerComponent(compositeDef);
}
}
@@ -156,7 +156,7 @@ public class AnnotationBeanNameGenerator implements BeanNameGenerator {
/**
* Derive a default bean name from the given bean definition.
* <p>The default implementation simply builds a decapitalized version
* of the short class name: e.g. "mypackage.MyJdbcDao" -> "myJdbcDao".
* of the short class name: e.g. "mypackage.MyJdbcDao" &rarr; "myJdbcDao".
* <p>Note that inner classes will thus have names of the form
* "outerClassName.InnerClassName", which because of the period in the
* name may be an issue if you are autowiring by name.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 the original author 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.context.annotation;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
@@ -424,40 +425,38 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
if (traceEnabled) {
logger.trace("Scanning " + resource);
}
if (resource.isReadable()) {
try {
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
if (isCandidateComponent(metadataReader)) {
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setSource(resource);
if (isCandidateComponent(sbd)) {
if (debugEnabled) {
logger.debug("Identified candidate component class: " + resource);
}
candidates.add(sbd);
}
else {
if (debugEnabled) {
logger.debug("Ignored because not a concrete top-level class: " + resource);
}
try {
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
if (isCandidateComponent(metadataReader)) {
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setSource(resource);
if (isCandidateComponent(sbd)) {
if (debugEnabled) {
logger.debug("Identified candidate component class: " + resource);
}
candidates.add(sbd);
}
else {
if (traceEnabled) {
logger.trace("Ignored because not matching any filter: " + resource);
if (debugEnabled) {
logger.debug("Ignored because not a concrete top-level class: " + resource);
}
}
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to read candidate component class: " + resource, ex);
else {
if (traceEnabled) {
logger.trace("Ignored because not matching any filter: " + resource);
}
}
}
else {
catch (FileNotFoundException ex) {
if (traceEnabled) {
logger.trace("Ignored because not readable: " + resource);
logger.trace("Ignored non-readable " + resource + ": " + ex.getMessage());
}
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to read candidate component class: " + resource, ex);
}
}
}
catch (IOException ex) {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -146,22 +146,27 @@ import org.springframework.util.StringValueResolver;
public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {
// Defensive reference to JNDI API for JDK 9+ (optional java.naming module)
private static final boolean jndiPresent = ClassUtils.isPresent(
"javax.naming.InitialContext", CommonAnnotationBeanPostProcessor.class.getClassLoader());
private static final Set<Class<? extends Annotation>> resourceAnnotationTypes = new LinkedHashSet<>(4);
@Nullable
private static final Class<? extends Annotation> webServiceRefClass;
@Nullable
private static final Class<? extends Annotation> ejbClass;
private static final Set<Class<? extends Annotation>> resourceAnnotationTypes = new LinkedHashSet<>(4);
static {
webServiceRefClass = loadAnnotationType("javax.xml.ws.WebServiceRef");
ejbClass = loadAnnotationType("javax.ejb.EJB");
resourceAnnotationTypes.add(Resource.class);
webServiceRefClass = loadAnnotationType("javax.xml.ws.WebServiceRef");
if (webServiceRefClass != null) {
resourceAnnotationTypes.add(webServiceRefClass);
}
ejbClass = loadAnnotationType("javax.ejb.EJB");
if (ejbClass != null) {
resourceAnnotationTypes.add(ejbClass);
}
@@ -174,7 +179,8 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
private boolean alwaysUseJndiLookup = false;
private transient BeanFactory jndiFactory = new SimpleJndiBeanFactory();
@Nullable
private transient BeanFactory jndiFactory;
@Nullable
private transient BeanFactory resourceFactory;
@@ -199,6 +205,11 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
setInitAnnotationType(PostConstruct.class);
setDestroyAnnotationType(PreDestroy.class);
ignoreResourceType("javax.xml.ws.WebServiceContext");
// java.naming module present on JDK 9+?
if (jndiPresent) {
this.jndiFactory = new SimpleJndiBeanFactory();
}
}
@@ -332,7 +343,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
}
private InjectionMetadata findResourceMetadata(String beanName, final Class<?> clazz, @Nullable PropertyValues pvs) {
private InjectionMetadata findResourceMetadata(String beanName, Class<?> clazz, @Nullable 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.
@@ -352,7 +363,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
return metadata;
}
private InjectionMetadata buildResourceMetadata(final Class<?> clazz) {
private InjectionMetadata buildResourceMetadata(Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, resourceAnnotationTypes)) {
return InjectionMetadata.EMPTY;
}
@@ -464,6 +475,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
public void releaseTarget(Object target) {
}
};
ProxyFactory pf = new ProxyFactory();
pf.setTargetSource(ts);
if (element.lookupType.isInterface()) {
@@ -484,12 +496,23 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
protected Object getResource(LookupElement element, @Nullable String requestingBeanName)
throws NoSuchBeanDefinitionException {
// JNDI lookup to perform?
String jndiName = null;
if (StringUtils.hasLength(element.mappedName)) {
return this.jndiFactory.getBean(element.mappedName, element.lookupType);
jndiName = element.mappedName;
}
if (this.alwaysUseJndiLookup) {
return this.jndiFactory.getBean(element.name, element.lookupType);
else if (this.alwaysUseJndiLookup) {
jndiName = element.name;
}
if (jndiName != null) {
if (this.jndiFactory == null) {
throw new NoSuchBeanDefinitionException(element.lookupType,
"No JNDI factory configured - specify the 'jndiFactory' property");
}
return this.jndiFactory.getBean(jndiName, element.lookupType);
}
// Regular resource autowiring
if (this.resourceFactory == null) {
throw new NoSuchBeanDefinitionException(element.lookupType,
"No resource factory configured - specify the 'resourceFactory' property");
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,13 +16,10 @@
package org.springframework.context.annotation;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
@@ -33,12 +30,7 @@ import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.filter.AbstractTypeHierarchyTraversingFilter;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.AspectJTypeFilter;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.core.type.filter.RegexPatternTypeFilter;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
@@ -73,7 +65,7 @@ class ComponentScanAnnotationParser {
}
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, String declaringClass) {
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
@@ -93,13 +85,17 @@ class ComponentScanAnnotationParser {
scanner.setResourcePattern(componentScan.getString("resourcePattern"));
for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
for (AnnotationAttributes includeFilterAttributes : componentScan.getAnnotationArray("includeFilters")) {
List<TypeFilter> typeFilters = TypeFilterUtils.createTypeFiltersFor(includeFilterAttributes, this.environment,
this.resourceLoader, this.registry);
for (TypeFilter typeFilter : typeFilters) {
scanner.addIncludeFilter(typeFilter);
}
}
for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
for (AnnotationAttributes excludeFilterAttributes : componentScan.getAnnotationArray("excludeFilters")) {
List<TypeFilter> typeFilters = TypeFilterUtils.createTypeFiltersFor(excludeFilterAttributes, this.environment,
this.resourceLoader, this.registry);
for (TypeFilter typeFilter : typeFilters) {
scanner.addExcludeFilter(typeFilter);
}
}
@@ -132,49 +128,4 @@ class ComponentScanAnnotationParser {
return scanner.doScan(StringUtils.toStringArray(basePackages));
}
private List<TypeFilter> typeFiltersFor(AnnotationAttributes filterAttributes) {
List<TypeFilter> typeFilters = new ArrayList<>();
FilterType filterType = filterAttributes.getEnum("type");
for (Class<?> filterClass : filterAttributes.getClassArray("classes")) {
switch (filterType) {
case ANNOTATION:
Assert.isAssignable(Annotation.class, filterClass,
"@ComponentScan ANNOTATION type filter requires an annotation type");
@SuppressWarnings("unchecked")
Class<Annotation> annotationType = (Class<Annotation>) filterClass;
typeFilters.add(new AnnotationTypeFilter(annotationType));
break;
case ASSIGNABLE_TYPE:
typeFilters.add(new AssignableTypeFilter(filterClass));
break;
case CUSTOM:
Assert.isAssignable(TypeFilter.class, filterClass,
"@ComponentScan CUSTOM type filter requires a TypeFilter implementation");
TypeFilter filter = ParserStrategyUtils.instantiateClass(filterClass, TypeFilter.class,
this.environment, this.resourceLoader, this.registry);
typeFilters.add(filter);
break;
default:
throw new IllegalArgumentException("Filter type not supported with Class value: " + filterType);
}
}
for (String expression : filterAttributes.getStringArray("pattern")) {
switch (filterType) {
case ASPECTJ:
typeFilters.add(new AspectJTypeFilter(expression, this.resourceLoader.getClassLoader()));
break;
case REGEX:
typeFilters.add(new RegexPatternTypeFilter(Pattern.compile(expression)));
break;
default:
throw new IllegalArgumentException("Filter type not supported with String pattern: " + filterType);
}
}
return typeFilters;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -129,7 +129,7 @@ import org.springframework.stereotype.Component;
* &#064;Configuration
* public class AppConfig {
*
* &#064Autowired Environment env;
* &#064;Autowired Environment env;
*
* &#064;Bean
* public MyBean myBean() {
@@ -149,7 +149,7 @@ import org.springframework.stereotype.Component;
* &#064;PropertySource("classpath:/com/acme/app.properties")
* public class AppConfig {
*
* &#064Inject Environment env;
* &#064;Inject Environment env;
*
* &#064;Bean
* public MyBean myBean() {
@@ -170,7 +170,7 @@ import org.springframework.stereotype.Component;
* &#064;PropertySource("classpath:/com/acme/app.properties")
* public class AppConfig {
*
* &#064Value("${bean.name}") String beanName;
* &#064;Value("${bean.name}") String beanName;
*
* &#064;Bean
* public MyBean myBean() {
@@ -297,7 +297,7 @@ import org.springframework.stereotype.Component;
* &#064;ImportResource("classpath:/com/acme/database-config.xml")
* public class AppConfig {
*
* &#064Inject DataSource dataSource; // from XML
* &#064;Inject DataSource dataSource; // from XML
*
* &#064;Bean
* public MyBean myBean() {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -453,8 +453,8 @@ class ConfigurationClassEnhancer {
* instance directly. If a FactoryBean instance is fetched through the container via &-dereferencing,
* it will not be proxied. This too is aligned with the way XML configuration works.
*/
private Object enhanceFactoryBean(final Object factoryBean, Class<?> exposedType,
final ConfigurableBeanFactory beanFactory, final String beanName) {
private Object enhanceFactoryBean(Object factoryBean, Class<?> exposedType,
ConfigurableBeanFactory beanFactory, String beanName) {
try {
Class<?> clazz = factoryBean.getClass();
@@ -489,8 +489,8 @@ class ConfigurationClassEnhancer {
return createCglibProxyForFactoryBean(factoryBean, beanFactory, beanName);
}
private Object createInterfaceProxyForFactoryBean(final Object factoryBean, Class<?> interfaceType,
final ConfigurableBeanFactory beanFactory, final String beanName) {
private Object createInterfaceProxyForFactoryBean(Object factoryBean, Class<?> interfaceType,
ConfigurableBeanFactory beanFactory, String beanName) {
return Proxy.newProxyInstance(
factoryBean.getClass().getClassLoader(), new Class<?>[] {interfaceType},
@@ -502,8 +502,8 @@ class ConfigurationClassEnhancer {
});
}
private Object createCglibProxyForFactoryBean(final Object factoryBean,
final ConfigurableBeanFactory beanFactory, final String beanName) {
private Object createCglibProxyForFactoryBean(Object factoryBean,
ConfigurableBeanFactory beanFactory, String beanName) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(factoryBean.getClass());
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -98,7 +98,7 @@ import java.lang.annotation.Target;
* &#064;EnableAspectJAutoProxy
* public class AppConfig {
*
* // no explicit &#064Bean definitions required
* // no explicit &#064;Bean definitions required
* }</pre>
*
* <b>Note: {@code @EnableAspectJAutoProxy} applies to its local application context only,
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,6 +47,11 @@ import java.lang.annotation.Target;
* or {@link javax.inject.Inject}: In that context, it leads to the creation of a
* lazy-resolution proxy for all affected dependencies, as an alternative to using
* {@link org.springframework.beans.factory.ObjectFactory} or {@link javax.inject.Provider}.
* Please note that such a lazy-resolution proxy will always be injected; if the target
* dependency does not exist, you will only be able to find out through an exception on
* invocation. As a consequence, such an injection point results in unintuitive behavior
* for optional dependencies. For a programmatic equivalent, allowing for lazy references
* with more sophistication, consider {@link org.springframework.beans.factory.ObjectProvider}.
*
* @author Chris Beams
* @author Juergen Hoeller
@@ -0,0 +1,119 @@
/*
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.context.annotation;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.AspectJTypeFilter;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.core.type.filter.RegexPatternTypeFilter;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.util.Assert;
/**
* Collection of utilities for working with {@link ComponentScan @ComponentScan}
* {@linkplain ComponentScan.Filter type filters}.
*
* @author Chris Beams
* @author Juergen Hoeller
* @author Sam Brannen
* @since 5.3.13
* @see ComponentScan.Filter
* @see org.springframework.core.type.filter.TypeFilter
*/
public abstract class TypeFilterUtils {
/**
* Create {@linkplain TypeFilter type filters} from the supplied
* {@link AnnotationAttributes}, such as those sourced from
* {@link ComponentScan#includeFilters()} or {@link ComponentScan#excludeFilters()}.
* <p>Each {@link TypeFilter} will be instantiated using an appropriate
* constructor, with {@code BeanClassLoaderAware}, {@code BeanFactoryAware},
* {@code EnvironmentAware}, and {@code ResourceLoaderAware} contracts
* invoked if they are implemented by the type filter.
* @param filterAttributes {@code AnnotationAttributes} for a
* {@link ComponentScan.Filter @Filter} declaration
* @param environment the {@code Environment} to make available to filters
* @param resourceLoader the {@code ResourceLoader} to make available to filters
* @param registry the {@code BeanDefinitionRegistry} to make available to filters
* as a {@link org.springframework.beans.factory.BeanFactory} if applicable
* @return a list of instantiated and configured type filters
* @see TypeFilter
* @see AnnotationTypeFilter
* @see AssignableTypeFilter
* @see AspectJTypeFilter
* @see RegexPatternTypeFilter
* @see org.springframework.beans.factory.BeanClassLoaderAware
* @see org.springframework.beans.factory.BeanFactoryAware
* @see org.springframework.context.EnvironmentAware
* @see org.springframework.context.ResourceLoaderAware
*/
public static List<TypeFilter> createTypeFiltersFor(AnnotationAttributes filterAttributes, Environment environment,
ResourceLoader resourceLoader, BeanDefinitionRegistry registry) {
List<TypeFilter> typeFilters = new ArrayList<>();
FilterType filterType = filterAttributes.getEnum("type");
for (Class<?> filterClass : filterAttributes.getClassArray("classes")) {
switch (filterType) {
case ANNOTATION:
Assert.isAssignable(Annotation.class, filterClass,
"@ComponentScan ANNOTATION type filter requires an annotation type");
@SuppressWarnings("unchecked")
Class<Annotation> annotationType = (Class<Annotation>) filterClass;
typeFilters.add(new AnnotationTypeFilter(annotationType));
break;
case ASSIGNABLE_TYPE:
typeFilters.add(new AssignableTypeFilter(filterClass));
break;
case CUSTOM:
Assert.isAssignable(TypeFilter.class, filterClass,
"@ComponentScan CUSTOM type filter requires a TypeFilter implementation");
TypeFilter filter = ParserStrategyUtils.instantiateClass(filterClass, TypeFilter.class,
environment, resourceLoader, registry);
typeFilters.add(filter);
break;
default:
throw new IllegalArgumentException("Filter type not supported with Class value: " + filterType);
}
}
for (String expression : filterAttributes.getStringArray("pattern")) {
switch (filterType) {
case ASPECTJ:
typeFilters.add(new AspectJTypeFilter(expression, resourceLoader.getClassLoader()));
break;
case REGEX:
typeFilters.add(new RegexPatternTypeFilter(Pattern.compile(expression)));
break;
default:
throw new IllegalArgumentException("Filter type not supported with String pattern: " + filterType);
}
}
return typeFilters;
}
}
@@ -75,7 +75,7 @@ public abstract class CachedExpressionEvaluator {
/**
* Return the {@link Expression} for the specified SpEL value
* <p>Parse the expression if it hasn't been already.
* <p>{@link #parseExpression(String) Parse the expression} if it hasn't been already.
* @param cache the cache to use
* @param elementKey the element on which the expression is defined
* @param expression the expression to parse
@@ -86,12 +86,21 @@ public abstract class CachedExpressionEvaluator {
ExpressionKey expressionKey = createKey(elementKey, expression);
Expression expr = cache.get(expressionKey);
if (expr == null) {
expr = getParser().parseExpression(expression);
expr = parseExpression(expression);
cache.put(expressionKey, expr);
}
return expr;
}
/**
* Parse the specified {@code expression}.
* @param expression the expression to parse
* @since 5.3.13
*/
protected Expression parseExpression(String expression) {
return getParser().parseExpression(expression);
}
private ExpressionKey createKey(AnnotatedElementKey elementKey, String expression) {
return new ExpressionKey(elementKey, expression);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ import org.springframework.beans.factory.BeanExpressionException;
import org.springframework.beans.factory.config.BeanExpressionContext;
import org.springframework.beans.factory.config.BeanExpressionResolver;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.ParserContext;
@@ -156,10 +157,10 @@ public class StandardBeanExpressionResolver implements BeanExpressionResolver {
sec.addPropertyAccessor(new EnvironmentAccessor());
sec.setBeanResolver(new BeanFactoryResolver(evalContext.getBeanFactory()));
sec.setTypeLocator(new StandardTypeLocator(evalContext.getBeanFactory().getBeanClassLoader()));
ConversionService conversionService = evalContext.getBeanFactory().getConversionService();
if (conversionService != null) {
sec.setTypeConverter(new StandardTypeConverter(conversionService));
}
sec.setTypeConverter(new StandardTypeConverter(() -> {
ConversionService cs = evalContext.getBeanFactory().getConversionService();
return (cs != null ? cs : DefaultConversionService.getSharedInstance());
}));
customizeEvaluationContext(sec);
this.evaluationCache.put(evalContext, sec);
}
@@ -107,7 +107,7 @@ public final class CandidateComponentsIndexLoader {
result.add(properties);
}
if (logger.isDebugEnabled()) {
logger.debug("Loaded " + result.size() + "] index(es)");
logger.debug("Loaded " + result.size() + " index(es)");
}
int totalCount = result.stream().mapToInt(Properties::size).sum();
return (totalCount > 0 ? new CandidateComponentsIndex(result) : null);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 the original author 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,18 +46,18 @@ import org.springframework.lang.Nullable;
*
* def context = new GenericGroovyApplicationContext()
* context.reader.beans {
* dataSource(BasicDataSource) { // <--- invokeMethod
* dataSource(BasicDataSource) { // &lt;--- invokeMethod
* driverClassName = "org.hsqldb.jdbcDriver"
* url = "jdbc:hsqldb:mem:grailsDB"
* username = "sa" // <-- setProperty
* username = "sa" // &lt;-- setProperty
* password = ""
* settings = [mynew:"setting"]
* }
* sessionFactory(SessionFactory) {
* dataSource = dataSource // <-- getProperty for retrieving references
* dataSource = dataSource // &lt;-- getProperty for retrieving references
* }
* myService(MyService) {
* nestedBean = { AnotherBean bean -> // <-- setProperty with closure for nested bean
* nestedBean = { AnotherBean bean -&gt; // &lt;-- setProperty with closure for nested bean
* dataSource = dataSource
* }
* }
@@ -84,7 +84,7 @@ import org.springframework.lang.Nullable;
* dataSource = dataSource
* }
* myService(MyService) {
* nestedBean = { AnotherBean bean ->
* nestedBean = { AnotherBean bean -&gt;
* dataSource = dataSource
* }
* }
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -185,9 +185,9 @@ public class PropertySourcesPlaceholderConfigurer extends PlaceholderConfigurerS
/**
* Implemented for compatibility with
* {@link org.springframework.beans.factory.config.PlaceholderConfigurerSupport}.
* @throws UnsupportedOperationException in this implementation
* @deprecated in favor of
* {@link #processProperties(ConfigurableListableBeanFactory, ConfigurablePropertyResolver)}
* @throws UnsupportedOperationException in this implementation
*/
@Override
@Deprecated
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -229,7 +229,7 @@ public class ReloadableResourceBundleMessageSource extends AbstractResourceBased
* for a Locale, after merging all specified resource bundles.
* Either fetches the holder from the cache or freshly loads it.
* <p>Only used when caching resource bundle contents forever, i.e.
* with cacheSeconds < 0. Therefore, merged properties are always
* with cacheSeconds &lt; 0. Therefore, merged properties are always
* cached forever.
*/
protected PropertiesHolder getMergedProperties(Locale locale) {
@@ -315,7 +315,7 @@ public class ReloadableResourceBundleMessageSource extends AbstractResourceBased
/**
* Calculate the filenames for the given bundle basename and Locale,
* appending language code, country code, and variant code.
* E.g.: basename "messages", Locale "de_AT_oo" -> "messages_de_AT_OO",
* <p>For example, basename "messages", Locale "de_AT_oo" &rarr; "messages_de_AT_OO",
* "messages_de_AT", "messages_de".
* <p>Follows the rules defined by {@link java.util.Locale#toString()}.
* @param basename the basename of the bundle
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.format;
import org.springframework.core.convert.converter.Converter;
@@ -37,7 +37,7 @@ import org.springframework.util.StringValueResolver;
* as {@code DefaultConversionService} exposes its own
* {@link DefaultConversionService#addDefaultConverters addDefaultConverters} method.
*
* <p>Automatically registers formatters for JSR-354 Money & Currency, JSR-310 Date-Time
* <p>Automatically registers formatters for JSR-354 Money &amp; Currency, JSR-310 Date-Time
* and/or Joda-Time 2.x, depending on the presence of the corresponding API on the classpath.
*
* @author Chris Beams
@@ -100,7 +100,7 @@ public class DefaultFormattingConversionService extends FormattingConversionServ
/**
* Add formatters appropriate for most environments: including number formatters,
* JSR-354 Money & Currency formatters, JSR-310 Date-Time and/or Joda-Time formatters,
* JSR-354 Money &amp; Currency formatters, JSR-310 Date-Time and/or Joda-Time formatters,
* depending on the presence of the corresponding API on the classpath.
* @param formatterRegistry the service to register default formatters with
*/
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -44,8 +44,8 @@ public interface JndiCallback<T> {
* <p>Implementations don't need to worry about error handling
* or cleanup, as the JndiTemplate class will handle this.
* @param ctx the current JNDI context
* @throws NamingException if thrown by JNDI methods
* @return a result object, or {@code null}
* @throws NamingException if thrown by JNDI methods
*/
@Nullable
T doInContext(Context ctx) throws NamingException;
@@ -56,7 +56,7 @@ import org.springframework.util.Assert;
* For example:
*
* <pre class="code">&lt;property name="jndiEnvironment"&gt;
* &lt;props>
* &lt;props&gt;
* &lt;prop key="java.naming.factory.initial"&gt;com.sun.jndi.cosnaming.CNCtxFactory&lt;/prop&gt;
* &lt;prop key="java.naming.provider.url"&gt;iiop://localhost:1050&lt;/prop&gt;
* &lt;/props&gt;
@@ -43,7 +43,7 @@ import org.springframework.util.ClassUtils;
* For example:
*
* <pre class="code">&lt;property name="jndiEnvironment"&gt;
* &lt;props>
* &lt;props&gt;
* &lt;prop key="java.naming.factory.initial"&gt;com.sun.jndi.cosnaming.CNCtxFactory&lt;/prop&gt;
* &lt;prop key="java.naming.provider.url"&gt;iiop://localhost:1050&lt;/prop&gt;
* &lt;/props&gt;
@@ -52,7 +52,7 @@ import org.springframework.util.ReflectionUtils;
* For example:
*
* <pre class="code">&lt;property name="jndiEnvironment"&gt;
* &lt;props>
* &lt;props&gt;
* &lt;prop key="java.naming.factory.initial"&gt;com.sun.jndi.cosnaming.CNCtxFactory&lt;/prop&gt;
* &lt;prop key="java.naming.provider.url"&gt;iiop://localhost:1050&lt;/prop&gt;
* &lt;/props&gt;
@@ -75,7 +75,6 @@ public class AsyncAnnotationAdvisor extends AbstractPointcutAdvisor implements B
* handle unexpected exception thrown by asynchronous method executions
* @see AnnotationAsyncExecutionInterceptor#getDefaultExecutor(BeanFactory)
*/
@SuppressWarnings("unchecked")
public AsyncAnnotationAdvisor(
@Nullable Executor executor, @Nullable AsyncUncaughtExceptionHandler exceptionHandler) {
@@ -171,7 +171,6 @@ public final class CronExpression {
* <li>{@code "@daily"} (or {@code "@midnight"}) to run once a day, i.e. {@code "0 0 0 * * *"},</li>
* <li>{@code "@hourly"} to run once an hour, i.e. {@code "0 0 * * * *"}.</li>
* </ul>
*
* @param expression the expression string to parse
* @return the parsed {@code CronExpression} object
* @throws IllegalArgumentException in the expression does not conform to
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2021 the original author 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,11 +105,11 @@ public class CronTrigger implements Trigger {
}
}
else {
date = new Date();
date = new Date(triggerContext.getClock().millis());
}
ZonedDateTime dateTime = ZonedDateTime.ofInstant(date.toInstant(), this.zoneId);
ZonedDateTime next = this.expression.next(dateTime);
return next != null ? Date.from(next.toInstant()) : null;
return (next != null ? Date.from(next.toInstant()) : null);
}
@@ -87,7 +87,7 @@ public class ResourceBundleThemeSource implements HierarchicalThemeSource, BeanC
/**
* Set the prefix that gets applied to the ResourceBundle basenames,
* i.e. the theme names.
* E.g.: basenamePrefix="test.", themeName="theme" -> basename="test.theme".
* E.g.: basenamePrefix="test.", themeName="theme" &rarr; basename="test.theme".
* <p>Note that ResourceBundle names are effectively classpath locations: As a
* consequence, the JDK's standard ResourceBundle treats dots as package separators.
* This means that "test.theme" is effectively equivalent to "test/theme",
@@ -83,8 +83,8 @@ public interface Errors {
* {@code pushNestedPath(String)} call.
* <p>Using the nested path stack allows to set temporary nested paths
* for subobjects without having to worry about a temporary path holder.
* <p>For example: current path "spouse.", pushNestedPath("child") ->
* result path "spouse.child."; popNestedPath() -> "spouse." again.
* <p>For example: current path "spouse.", pushNestedPath("child") &rarr;
* result path "spouse.child."; popNestedPath() &rarr; "spouse." again.
* @param subPath the sub path to push onto the nested path stack
* @see #popNestedPath
*/
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,7 +33,7 @@ package org.springframework.validation;
* wholly of whitespace), and that any password that is present is
* at least {@code 'MINIMUM_PASSWORD_LENGTH'} characters in length.
*
* <pre class="code"> public class UserLoginValidator implements Validator {
* <pre class="code">public class UserLoginValidator implements Validator {
*
* private static final int MINIMUM_PASSWORD_LENGTH = 6;
*
@@ -46,7 +46,7 @@ package org.springframework.validation;
* ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password", "field.required");
* UserLogin login = (UserLogin) target;
* if (login.getPassword() != null
* && login.getPassword().trim().length() < MINIMUM_PASSWORD_LENGTH) {
* &amp;&amp; login.getPassword().trim().length() &lt; MINIMUM_PASSWORD_LENGTH) {
* errors.rejectValue("password", "field.min.length",
* new Object[]{Integer.valueOf(MINIMUM_PASSWORD_LENGTH)},
* "The password must be at least [" + MINIMUM_PASSWORD_LENGTH + "] characters in length.");
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,6 +47,7 @@ import org.springframework.util.Assert;
public abstract class FooServiceImpl implements FooService {
// Just to test ASM5's bytecode parsing of INVOKESPECIAL/STATIC on interfaces
@SuppressWarnings("unused")
private static final Comparator<MessageBean> COMPARATOR_BY_MESSAGE = Comparator.comparing(MessageBean::getMessage);
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.aop.aspectj;
import org.aspectj.lang.ProceedingJoinPoint;
@@ -48,7 +48,6 @@ import org.springframework.core.NestedRuntimeException;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.lang.Nullable;
import org.springframework.util.StopWatch;
import static org.assertj.core.api.Assertions.assertThat;
@@ -310,12 +309,6 @@ public class AspectJAutoProxyCreatorTests {
return String.format("%s-%s", getClass().getSimpleName(), fileSuffix);
}
private void assertStopWatchTimeLimit(final StopWatch sw, final long maxTimeMillis) {
long totalTimeMillis = sw.getTotalTimeMillis();
assertThat(totalTimeMillis < maxTimeMillis).as("'" + sw.getLastTaskName() + "' took too long: expected less than<" + maxTimeMillis +
"> ms, actual<" + totalTimeMillis + "> ms.").isTrue();
}
}
@Aspect("pertarget(execution(* *.getSpouse()))")
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -513,6 +513,7 @@ public class CglibProxyTests extends AbstractAopProxyTests implements Serializab
this.name = name;
}
@SuppressWarnings("unused")
public String getName() {
return this.name;
}
@@ -137,6 +137,7 @@ public class AggressiveFactoryBeanInstantiationTests {
static class ExceptionInInitializer {
@SuppressWarnings("unused")
private static final int ERROR = callInClinit();
private static int callInClinit() {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,7 +25,6 @@ import org.springframework.beans.testfixture.beans.TestBean;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests cornering the issue reported in SPR-8080. If the product of a @Bean method
* was @Autowired into a configuration class while at the same time the declaring
@@ -34,7 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* 'currently in creation' status of the autowired bean and result in creating multiple
* instances of the given @Bean, violating container scoping / singleton semantics.
*
* This is resolved through no longer relying on 'currently in creation' status, but
* <p>This is resolved through no longer relying on 'currently in creation' status, but
* rather on a thread local that informs the enhanced bean method implementation whether
* the factory is the caller or not.
*
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -1956,6 +1956,7 @@ class ConfigurationClassPostProcessorTests {
}
// Unrelated, not to be considered as a factory method
@SuppressWarnings("unused")
private boolean testBean(boolean param) {
return param;
}
@@ -1985,6 +1986,7 @@ class ConfigurationClassPostProcessorTests {
}
// Unrelated, not to be considered as a factory method
@SuppressWarnings("unused")
private boolean testBean(boolean param) {
return param;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +26,6 @@ import org.springframework.context.support.GenericXmlApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Chris Beams
* @author Juergen Hoeller
@@ -47,6 +46,7 @@ public class DestroyMethodInferenceTests {
WithLocalShutdownMethod c7 = ctx.getBean("c7", WithLocalShutdownMethod.class);
WithInheritedCloseMethod c8 = ctx.getBean("c8", WithInheritedCloseMethod.class);
WithDisposableBean c9 = ctx.getBean("c9", WithDisposableBean.class);
WithAutoCloseable c10 = ctx.getBean("c10", WithAutoCloseable.class);
assertThat(c0.closed).as("c0").isFalse();
assertThat(c1.closed).as("c1").isFalse();
@@ -58,6 +58,8 @@ public class DestroyMethodInferenceTests {
assertThat(c7.closed).as("c7").isFalse();
assertThat(c8.closed).as("c8").isFalse();
assertThat(c9.closed).as("c9").isFalse();
assertThat(c10.closed).as("c10").isFalse();
ctx.close();
assertThat(c0.closed).as("c0").isTrue();
assertThat(c1.closed).as("c1").isTrue();
@@ -69,6 +71,7 @@ public class DestroyMethodInferenceTests {
assertThat(c7.closed).as("c7").isTrue();
assertThat(c8.closed).as("c8").isFalse();
assertThat(c9.closed).as("c9").isTrue();
assertThat(c10.closed).as("c10").isTrue();
}
@Test
@@ -80,21 +83,29 @@ public class DestroyMethodInferenceTests {
WithLocalCloseMethod x3 = ctx.getBean("x3", WithLocalCloseMethod.class);
WithNoCloseMethod x4 = ctx.getBean("x4", WithNoCloseMethod.class);
WithInheritedCloseMethod x8 = ctx.getBean("x8", WithInheritedCloseMethod.class);
WithDisposableBean x9 = ctx.getBean("x9", WithDisposableBean.class);
WithAutoCloseable x10 = ctx.getBean("x10", WithAutoCloseable.class);
assertThat(x1.closed).isFalse();
assertThat(x2.closed).isFalse();
assertThat(x3.closed).isFalse();
assertThat(x4.closed).isFalse();
assertThat(x8.closed).isFalse();
assertThat(x9.closed).isFalse();
assertThat(x10.closed).isFalse();
ctx.close();
assertThat(x1.closed).isFalse();
assertThat(x2.closed).isTrue();
assertThat(x3.closed).isTrue();
assertThat(x4.closed).isFalse();
assertThat(x8.closed).isFalse();
assertThat(x9.closed).isTrue();
assertThat(x10.closed).isTrue();
}
@Configuration
@Configuration(proxyBeanMethods = false)
static class Config {
@Bean(destroyMethod = "explicitClose")
@@ -155,6 +166,11 @@ public class DestroyMethodInferenceTests {
public WithDisposableBean c9() {
return new WithDisposableBean();
}
@Bean
public WithAutoCloseable c10() {
return new WithAutoCloseable();
}
}
@@ -189,17 +205,6 @@ public class DestroyMethodInferenceTests {
}
static class WithDisposableBean implements DisposableBean {
boolean closed = false;
@Override
public void destroy() {
closed = true;
}
}
static class WithNoCloseMethod {
boolean closed = false;
@@ -215,4 +220,26 @@ public class DestroyMethodInferenceTests {
}
}
static class WithDisposableBean implements DisposableBean {
boolean closed = false;
@Override
public void destroy() {
closed = true;
}
}
static class WithAutoCloseable implements AutoCloseable {
boolean closed = false;
@Override
public void close() {
closed = true;
}
}
}
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.context.annotation;
import org.junit.jupiter.api.Test;
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -61,7 +61,7 @@ public class ParserStrategyUtilsTests {
@BeforeEach
void setup() {
MockitoAnnotations.initMocks(this);
MockitoAnnotations.openMocks(this);
given(this.resourceLoader.getClassLoader()).willReturn(this.beanClassLoader);
}
@@ -74,6 +74,7 @@ public class Spr12278Tests {
private final String autowiredName;
// No @Autowired - implicit wiring
@SuppressWarnings("unused")
public SingleConstructorComponent(String autowiredName) {
this.autowiredName = autowiredName;
}
@@ -88,11 +89,13 @@ public class Spr12278Tests {
this.name = name;
}
@SuppressWarnings("unused")
public TwoConstructorsComponent() {
this("fallback");
}
}
@SuppressWarnings("unused")
private static class TwoSpecificConstructorsComponent {
private final Integer counter;
@@ -70,6 +70,7 @@ public class Spr16179Tests {
Assembler<Page<String>> assembler2;
@Autowired(required = false)
@SuppressWarnings("rawtypes")
Assembler<Page> assembler3;
@Autowired(required = false)
@@ -42,7 +42,6 @@ import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.beans.factory.config.ListFactoryBean;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
@@ -247,7 +246,9 @@ public class ConfigurationClassProcessingTests {
public void configurationWithPostProcessor() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(ConfigWithPostProcessor.class);
RootBeanDefinition placeholderConfigurer = new RootBeanDefinition(PropertyPlaceholderConfigurer.class);
@SuppressWarnings("deprecation")
RootBeanDefinition placeholderConfigurer = new RootBeanDefinition(
org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.class);
placeholderConfigurer.getPropertyValues().add("properties", "myProp=myValue");
ctx.registerBeanDefinition("placeholderConfigurer", placeholderConfigurer);
ctx.refresh();
@@ -536,6 +537,7 @@ public class ConfigurationClassProcessingTests {
String nameSuffix = "-processed-" + myProp;
@SuppressWarnings("unused")
public void setNameSuffix(String nameSuffix) {
this.nameSuffix = nameSuffix;
}
@@ -552,10 +554,6 @@ public class ConfigurationClassProcessingTests {
public Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
public int getOrder() {
return 0;
}
};
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,7 +25,6 @@ import org.junit.jupiter.api.Test;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader;
import org.springframework.beans.testfixture.beans.TestBean;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
@@ -166,8 +165,10 @@ public class ImportResourceTests {
}
}
@SuppressWarnings("deprecation")
@Configuration
@ImportResource(locations = "classpath:org/springframework/context/annotation/configuration/ImportNonXmlResourceConfig-context.properties", reader = PropertiesBeanDefinitionReader.class)
@ImportResource(locations = "classpath:org/springframework/context/annotation/configuration/ImportNonXmlResourceConfig-context.properties",
reader = org.springframework.beans.factory.support.PropertiesBeanDefinitionReader.class)
static class ImportNonXmlResourceConfig {
}
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2021 the original author 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,6 +59,7 @@ public class ImportWithConditionTests {
protected static class ConditionalThenUnconditional {
@Autowired
@SuppressWarnings("unused")
private BeanOne beanOne;
}
@@ -68,6 +69,7 @@ public class ImportWithConditionTests {
protected static class UnconditionalThenConditional {
@Autowired
@SuppressWarnings("unused")
private BeanOne beanOne;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,6 +47,7 @@ public class ImportedConfigurationClassEnhancementTests {
autowiredConfigClassIsEnhanced(ConfigThatDoesNotImport.class, ConfigToBeAutowired.class);
}
@SuppressWarnings("deprecation")
private void autowiredConfigClassIsEnhanced(Class<?>... configClasses) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(configClasses);
Config config = ctx.getBean(Config.class);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,6 +32,7 @@ import static org.assertj.core.api.Assertions.assertThat;
public class Spr7167Tests {
@SuppressWarnings("deprecation")
@Test
public void test() {
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(MyConfig.class);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -67,6 +67,17 @@ public class MapAccessorTests {
assertThat(ex.getValue(sec,mapGetter)).isEqualTo("bar");
assertThat(SpelCompiler.compile(ex)).isTrue();
assertThat(ex.getValue(sec,mapGetter)).isEqualTo("bar");
// basic isWritable
ex = sep.parseExpression("foo");
assertThat(ex.isWritable(sec,testMap)).isTrue();
// basic write
ex = sep.parseExpression("foo2");
ex.setValue(sec, testMap, "bar2");
assertThat(ex.getValue(sec,testMap)).isEqualTo("bar2");
assertThat(SpelCompiler.compile(ex)).isTrue();
assertThat(ex.getValue(sec,testMap)).isEqualTo("bar2");
}
public static class MapGetter {
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,7 +22,6 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
@@ -75,6 +74,7 @@ public class BeanFactoryPostProcessorTests {
}
@Test
@SuppressWarnings("deprecation")
public void testMultipleDefinedBeanFactoryPostProcessors() {
StaticApplicationContext ac = new StaticApplicationContext();
ac.registerSingleton("tb1", TestBean.class);
@@ -84,7 +84,7 @@ public class BeanFactoryPostProcessorTests {
ac.registerSingleton("bfpp1", TestBeanFactoryPostProcessor.class, pvs1);
MutablePropertyValues pvs2 = new MutablePropertyValues();
pvs2.add("properties", "key=value");
ac.registerSingleton("bfpp2", PropertyPlaceholderConfigurer.class, pvs2);
ac.registerSingleton("bfpp2", org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.class, pvs2);
ac.refresh();
TestBeanFactoryPostProcessor bfpp = (TestBeanFactoryPostProcessor) ac.getBean("bfpp1");
assertThat(bfpp.initValue).isEqualTo("value");
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,6 +38,7 @@ import static org.mockito.Mockito.mock;
* @author Stephane Nicoll
* @author Sam Brannen
*/
@SuppressWarnings("deprecation")
class LiveBeansViewTests {
private final MockEnvironment environment = new MockEnvironment();
@@ -43,6 +43,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
* @author Sam Brannen
* @see org.springframework.beans.factory.config.PropertyResourceConfigurerTests
*/
@SuppressWarnings("deprecation")
public class PropertyResourceConfigurerIntegrationTests {
@Test
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 the original author 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,6 @@ import static org.springframework.beans.factory.support.BeanDefinitionBuilder.ro
*/
public class PropertySourcesPlaceholderConfigurerTests {
@Test
public void replacementFromEnvironmentProperties() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
@@ -397,6 +396,7 @@ public class PropertySourcesPlaceholderConfigurerTests {
return name;
}
@SuppressWarnings("unused")
public void setName(Optional<String> name) {
this.name = name;
}

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