Skip to content

Commit c74f897

Browse files
committed
Merge branch '6.2.x'
# Conflicts: # spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java
2 parents 639af7b + 143985e commit c74f897

File tree

3 files changed

+44
-4
lines changed

3 files changed

+44
-4
lines changed

framework-docs/modules/ROOT/pages/core/beans/annotation-config/autowired.adoc

+10-3
Original file line numberDiff line numberDiff line change
@@ -444,9 +444,9 @@ through Java 8's `java.util.Optional`, as the following example shows:
444444
}
445445
----
446446

447-
You can also use a `@Nullable` annotation (of any kind in any package -- for example,
448-
`javax.annotation.Nullable` from JSR-305) or just leverage Kotlin built-in null-safety
449-
support:
447+
You can also use a parameter-level `@Nullable` annotation (of any kind in any package --
448+
for example, `javax.annotation.Nullable` from JSR-305) or just leverage Kotlin built-in
449+
null-safety support:
450450

451451
[tabs]
452452
======
@@ -477,6 +477,13 @@ Kotlin::
477477
----
478478
======
479479

480+
[NOTE]
481+
====
482+
A type-level `@Nullable` annotation such as from JSpecify is not supported in Spring
483+
Framework 6.2 yet. You need to upgrade to Spring Framework 7.0 where the framework
484+
detects type-level annotations and consistently declares JSpecify in its own codebase.
485+
====
486+
480487
You can also use `@Autowired` for interfaces that are well-known resolvable
481488
dependencies: `BeanFactory`, `ApplicationContext`, `Environment`, `ResourceLoader`,
482489
`ApplicationEventPublisher`, and `MessageSource`. These interfaces and their extended

spring-beans/src/main/java/org/springframework/beans/factory/ObjectProvider.java

+16-1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,21 @@
4747
* Alternatively, you may implement the specific methods that your callers expect,
4848
* for example, just {@link #getObject()} or {@link #getIfAvailable()}.
4949
*
50+
* <p>Note that {@link #getObject()} never returns {@code null} - it will throw a
51+
* {@link NoSuchBeanDefinitionException} instead -, whereas {@link #getIfAvailable()}
52+
* will return {@code null} if no matching bean is present at all. However, both
53+
* methods will throw a {@link NoUniqueBeanDefinitionException} if more than one
54+
* matching bean is found without a clear unique winner (see below). Last but not
55+
* least, {@link #getIfUnique()} will return {@code null} both when no matching bean
56+
* is found and when more than one matching bean is found without a unique winner.
57+
*
58+
* <p>Uniqueness is generally up to the container's candidate resolution algorithm
59+
* but always honors the "primary" flag (with only one of the candidate beans marked
60+
* as primary) and the "fallback" flag (with only one of the candidate beans not
61+
* marked as fallback). The default-candidate flag is consistently taken into
62+
* account as well, even for non-annotation-based injection points, with a single
63+
* default candidate winning in case of no clear primary/fallback indication.
64+
*
5065
* @author Juergen Hoeller
5166
* @since 4.3
5267
* @param <T> the object type
@@ -187,7 +202,7 @@ default T getIfUnique(Supplier<T> defaultSupplier) throws BeansException {
187202
* if unique (not called otherwise)
188203
* @throws BeansException in case of creation errors
189204
* @since 5.0
190-
* @see #getIfAvailable()
205+
* @see #getIfUnique()
191206
*/
192207
default void ifUnique(Consumer<T> dependencyConsumer) throws BeansException {
193208
T dependency = getIfUnique();

spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java

+18
Original file line numberDiff line numberDiff line change
@@ -1683,6 +1683,24 @@ void getBeanByTypeWithUniqueNonFallbackDefinition() {
16831683
assertThat(lbf.containsSingleton("bd1")).isFalse();
16841684
}
16851685

1686+
@Test
1687+
void getBeanByTypeWithPrimaryAndUniqueNonFallbackDefinition() {
1688+
RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
1689+
bd1.setLazyInit(true);
1690+
bd1.setFallback(true);
1691+
RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
1692+
bd2.setPrimary(true);
1693+
bd2.setFallback(true);
1694+
RootBeanDefinition bd3 = new RootBeanDefinition(TestBean.class);
1695+
lbf.registerBeanDefinition("bd1", bd1);
1696+
lbf.registerBeanDefinition("bd2", bd2);
1697+
lbf.registerBeanDefinition("bd3", bd3);
1698+
1699+
TestBean bean = lbf.getBean(TestBean.class);
1700+
assertThat(bean.getBeanName()).isEqualTo("bd2");
1701+
assertThat(lbf.containsSingleton("bd1")).isFalse();
1702+
}
1703+
16861704
@Test
16871705
void getBeanByTypeWithUniqueNonFallbackAndUniqueNonDefaultDefinition() {
16881706
RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);

0 commit comments

Comments
 (0)