Autowiring implicitely Kotlin primary constructors
when there are secondary constructors has side effects
on ConstructorResolver. It seems reasonable to
require explicit @Autowired annotation in such case.
With this commit, implicit autowiring of Kotlin
primary constructors is only performed when there
is a primary constructor defined alone or with
a default constructor (define explicitly or
generated via the kotlin-noarg compiler plugin
or via optional constructor parameters with default
values).
Issue: SPR-16022
Includes fixes for invalid exception declarations in Mockito-based unit tests. Also includes FreeMarker 2.3.27, Commons Pool 2.4.3, JSON-P 1.1.2.
Issue: SPR-16157
Includes unified detection of Kotlin's optional parameters in MethodParameter.isOptional(), reduces BeanUtils.findPrimaryConstructor to Kotlin semantics (for reuse in AutowiredAnnotationBeanPostProcessor), and finally introduces a common KotlinDetector delegate with an isKotlinType(Class) check.
Issue: SPR-15877
Issue: SPR-16020
This commit introduces the following changes.
1) It adds a new Spring @NonNull annotation which allows to apply
@NonNullApi semantic on a specific element, like @Nullable does.
Combined with @Nullable, it allows partial null-safety support when
package granularity is too broad.
2) @Nullable and @NonNull can apply to ElementType.TYPE_USE in order
to be used on generic type arguments (SPR-15942).
3) Annotations does not apply to ElementType.TYPE_PARAMETER anymore
since it is not supported yet (applicability for such use case is
controversial and need to be discussed).
4) @NonNullApi does not apply to ElementType.FIELD anymore since in a
lot of use cases (private, protected) it is not part for the public API
+ its usage should remain opt-in. A dedicated @NonNullFields annotation
has been added in order to set fields default to non-nullable.
5) Updated Javadoc and reference documentation.
Issue: SPR-15756
The main `build.gradle` file contains now only the common build
infrastructure; all module-specific build configurations have
been moved to their own build file.
Issue: SPR-15885
Bean-derived null values may still get passed into bean properties and injection points but only if those are declared as non-required. Note that getBean will never return null; a manual bean.equals(null) / "null".equals(bean.toString()) check identifies expected null values now. This will only ever happen with custom FactoryBeans or factory methods returning null - and since all common cases are handled by autowiring or bean property values in bean definitions, there should be no need to ever manually check for such a null value received from getBean.
Issue: SPR-15829
By using function literals with receiver, we can avoid requiring
lambda parameters for a shorter and nicer syntax. Based on a
proposal from Joseph Taylor.
Issue: SPR-15815
This commit ensure that null-safety is consistent between
getters and setters in order to be able to provide beans
with properties with a common type when type safety is
taken in account like with Kotlin.
It also add a few missing property level @Nullable
annotations.
Issue: SPR-15792
As a follow-up of the ApplicationContext Kotlin extensions, close to
the Kotlin functional WebFlux DSL and partially inspired of the
Groovy/Scala bean configuration DSL, this commit introduces a
lightweight Kotlin DSL for functional bean declaration.
It allows declaring beans as following:
beans {
bean<Foo>()
profile("bar") {
bean<Bar>("bar", scope = Scope.PROTOTYPE)
}
environment({ it.activeProfiles.contains("baz") }) {
bean { Baz(it.ref()) }
bean { Baz(it.ref("bar")) }
}
}
Advantages compared to Regular ApplicationContext API are:
- No exposure of low-level ApplicationContext API
- Focused DSL easier to read, but also easier to write with a fewer
entries in the auto-complete
- Declarative syntax instead of functions with verbs like registerBeans
while still allowing programmatic registration of beans if needed
- Such DSL is idiomatic in Kotlin
- No need to have an ApplicationContext instance to write how you
register your beans since beans { } DSL is conceptually a
Consumer<GenericApplicationContext>
This DSL effectively replaces ApplicationContext Kotlin extensions as
the recommended way to register beans in a functional way with Kotlin.
Issue: SPR-15755
This commits extends nullability declarations to the field level, formalizing the interaction between methods and their underlying fields and therefore avoiding any nullability mismatch.
Issue: SPR-15720
This commit introduces LocaleContextResolver interface, which is used
at ServerWebExchange level to resolve Locale, TimeZone and other i18n
related informations.
It follows Spring MVC locale resolution patterns with a few differences:
- Only LocaleContextResolver is supported since LocaleResolver is less
flexible
- Support is implemented in the org.springframework.web.server.i18n
package of spring-web module rather than in spring-webflux in order
to be able to leverage it at ServerWebExchange level
2 implementations are provided:
- FixedLocaleContextResolver
- AcceptHeaderLocaleContextResolver
It can be configured with both functional or annotation-based APIs.
Issue: SPR-15036
This commit also removes nullability from two common spots: ResolvableType.getType() and TargetSource.getTarget(), both of which are never effectively null with any regular implementation. For such scenarios, a non-null empty type/target is the cleaner contract.
Issue: SPR-15540
Beyond just formally declaring the current behavior, this revision actually enforces non-null behavior in selected signatures now, not tolerating null values anymore when not explicitly documented. It also changes some utility methods with historic null-in/null-out tolerance towards enforced non-null return values, making them a proper citizen in non-null assignments.
Some issues are left as to-do: in particular a thorough revision of spring-test, and a few tests with unclear failures (ignored as "TODO: NULLABLE") to be sorted out in a follow-up commit.
Issue: SPR-15540
Defining nullability of some API like EnvironmentCapable
or ConditionContext causes issues in Spring Boot because
in the context where they are used, it is known for sure
they will return non-null values even if their API can in
other context return null values.
It is better in this case for both Java and Kotlin to
not define at all the nullabity of such API.
In practice, this is achieved by removing the package level
@NonNullApi annotation and adding it only on the
relevant classes.
Issue: SPR-15540
This commit introduces 2 new @Nullable and @NonNullApi
annotations that leverage JSR 305 (dormant but available via
Findbugs jsr305 dependency and already used by libraries
like OkHttp) meta-annotations to specify explicitly
null-safety of Spring Framework parameters and return values.
In order to avoid adding too much annotations, the
default is set at package level with @NonNullApi and
@Nullable annotations are added when needed at parameter or
return value level. These annotations are intended to be used
on Spring Framework itself but also by other Spring projects.
@Nullable annotations have been introduced based on Javadoc
and search of patterns like "return null;". It is expected that
nullability of Spring Framework API will be polished with
complementary commits.
In practice, this will make the whole Spring Framework API
null-safe for Kotlin projects (when KT-10942 will be fixed)
since Kotlin will be able to leverage these annotations to
know if a parameter or a return value is nullable or not. But
this is also useful for Java developers as well since IntelliJ
IDEA, for example, also understands these annotations to
generate warnings when unsafe nullable usages are detected.
Issue: SPR-15540
This commit improves `AbstractValueAdaptingCache` to throw a dedicated
exception if `allowNullValues` is `false` and a `null` value is provided
anyway. This avoid a lower-level exception from the cache library that
will miss some context.
Issue: SPR-15173
Put the lambda parameter at the end and use a function
instead of a supplier to be able to register beans like this:
val context = GenericApplicationContext()
context.registerBean(Foo::class)
context.registerBean{ Bar(it.getBean(Foo::class)) }
Issue: SPR-15118
Based on an idea from Mario Arias, we can avoid requiring specifying
explicitly Supplier lambda type in Kotlin API by declaring the supplier
parameter as "crossinline supplier: () -> T" instead of
"supplier: Supplier<T>".
Issue: SPR-15118