This is an automated email from the ASF dual-hosted git repository. jamesbognar pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/juneau.git
commit f086b391eb7acfdbb34d7da49df95954f57ccdd5 Author: James Bognar <[email protected]> AuthorDate: Fri May 8 14:32:49 2026 -0400 refactor(inject): TODO-15 phase-3 batch 8 — retire legacy SpringBeanStore The legacy SpringBeanStore (v1, extending the legacy cp.BasicBeanStore) became unused once SpringRestServlet flipped to SpringBeanStore2 in batch-6. Its only remaining caller was its own unit test. Changes: - Deleted juneau-rest-server-springboot/.../SpringBeanStore.java (86 lines). - Deleted juneau-utest/.../SpringBeanStore_Test.java (177 lines); SpringBeanStore2_Test already covers the surviving v2 implementation. - Updated four Javadoc references (RestInject, BeanContext, Bean, juneau-commons function/package-info) to mention SpringBeanStore2 instead of the deleted v1 class so the docs reflect the only available bridge. - Marked the Javadoc-cleanup item complete in todo/TODO-15: survey shows RestInject / RestInit / Name / Named already carry zero legacy references (TODO entry was stale); HttpPartParser / HttpPartSerializer still depend on ContextBeanCreator and stay gated on its v2 migration. Co-authored-by: Cursor <[email protected]> --- .../juneau/commons/function/package-info.java | 6 +- .../main/java/org/apache/juneau/BeanContext.java | 4 +- .../java/org/apache/juneau/annotation/Bean.java | 2 +- .../juneau/rest/springboot/SpringBeanStore.java | 87 ---------- .../apache/juneau/rest/annotation/RestInject.java | 2 +- .../rest/springboot/SpringBeanStore_Test.java | 178 --------------------- todo/TODO-15-replace-basicbeanstore-with-v2.md | 2 +- 7 files changed, 8 insertions(+), 273 deletions(-) diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/function/package-info.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/function/package-info.java index d4b239e0af..165cc72ec2 100644 --- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/function/package-info.java +++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/function/package-info.java @@ -381,7 +381,7 @@ * <p> * Spring-managed beans (e.g. a {@code DataSource}) can be injected into streaming implementations * without constructor scanning or reflection. Register the factories as Spring beans, then wire - * the {@code SpringBeanStore} into the Juneau context so the marshaller can resolve them at + * the {@code SpringBeanStore2} into the Juneau context so the marshaller can resolve them at * runtime. * </p> * @@ -407,7 +407,7 @@ * } * </p> * - * <h5 class='figure'>Wiring the SpringBeanStore into a REST resource</h5> + * <h5 class='figure'>Wiring the SpringBeanStore2 into a REST resource</h5> * <p class='bjava'> * <ja>@Rest</ja> * <jk>public class</jk> EmployeeResource <jk>extends</jk> BasicSpringRestServlet { @@ -418,7 +418,7 @@ * <ja>@Override</ja> * <jk>protected</jk> BeanContext.Builder createBeanContext(RestContext.Builder <jv>rcBuilder</jv>) { * <jk>return super</jk>.createBeanContext(<jv>rcBuilder</jv>) - * .beanStore(<jk>new</jk> SpringBeanStore(<jv>appCtx</jv>)); + * .beanStore(<jk>new</jk> SpringBeanStore2(<jv>appCtx</jv>)); * } * } * </p> diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java index 48085d4f21..15ae62abaf 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java @@ -1734,7 +1734,7 @@ public class BeanContext extends Context implements ConversionFinder { * before attempting direct instantiation. * * <p> - * Typically set to a {@code SpringBeanStore} wrapping the application's + * Typically set to a {@code SpringBeanStore2} wrapping the application's * {@code ApplicationContext} so that Spring-managed factories are resolved automatically. * * <h5 class='section'>Example:</h5> @@ -1744,7 +1744,7 @@ public class BeanContext extends Context implements ConversionFinder { * * <ja>@Override</ja> * <jk>protected</jk> BeanContext createBeanContext(BeanContext.Builder <jv>builder</jv>) { - * <jk>return</jk> <jv>builder</jv>.beanStore(<jk>new</jk> SpringBeanStore(<jv>ctx</jv>)).build(); + * <jk>return</jk> <jv>builder</jv>.beanStore(<jk>new</jk> SpringBeanStore2(<jv>ctx</jv>)).build(); * } * } * </p> diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Bean.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Bean.java index 7e840b8731..d786ae7953 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Bean.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/annotation/Bean.java @@ -68,7 +68,7 @@ public @interface Bean { * When a factory class is specified, the framework resolves it in the following order: * <ol> * <li>Look up the factory class in the configured {@link org.apache.juneau.commons.inject.BeanStore} - * (e.g. a Spring {@code ApplicationContext} wrapped in a {@code SpringBeanStore}) + * (e.g. a Spring {@code ApplicationContext} wrapped in a {@code SpringBeanStore2}) * <li>Attempt direct instantiation via no-arg constructor or {@code getInstance()} static method * <li>Throw {@link IllegalArgumentException} if both fail * </ol> diff --git a/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/SpringBeanStore.java b/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/SpringBeanStore.java deleted file mode 100644 index 6931a07405..0000000000 --- a/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/SpringBeanStore.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.juneau.rest.springboot; - -import static org.apache.juneau.commons.utils.Utils.*; - -import java.util.*; - -import org.apache.juneau.cp.*; -import org.springframework.context.*; - -/** - * A bean store that uses Spring bean resolution to find beans if they're not already in this store. - * - * <h5 class='section'>See Also:</h5><ul> - * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauRestServerSpringbootBasics">juneau-rest-server-springboot Basics</a> - * </ul> - */ -public class SpringBeanStore extends BasicBeanStore { - - private final Optional<ApplicationContext> appContext; - - /** - * Constructor. - * - * @param appContext The Spring application context used to resolve beans. - * @param parent The parent REST object bean store. Can be <jk>null</jk>. - * @param resource The REST object. Can be <jk>null</jk>. - */ - public SpringBeanStore(Optional<ApplicationContext> appContext, Optional<BasicBeanStore> parent, Object resource) { - super(create().parent(parent.orElse(null))); - this.appContext = appContext; - } - - @Override /* Overridden from BasicBeanStore */ - public SpringBeanStore clear() { - super.clear(); - return this; - } - - @Override - public <T> Optional<T> getBean(Class<T> c) { - try { - var o = super.getBean(c); - if (o.isPresent()) - return o; - if (appContext.isPresent()) { - return opt(appContext.get().getBeanProvider(c).getIfAvailable()); - } - } catch (Exception e) { - e.printStackTrace(); - } - return opte(); - } - - @Override - public <T> Optional<T> getBean(Class<T> c, String name) { - try { - var o = super.getBean(c, name); - if (o.isPresent()) - return o; - if (appContext.isPresent()) { - var ctx = appContext.get(); - if (nn(name)) - return opt(ctx.containsBean(name) ? appContext.get().getBean(name, c) : null); - return opt(appContext.get().getBean(c)); - } - } catch (Exception e) { - e.printStackTrace(); - } - return opte(); - } -} \ No newline at end of file diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestInject.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestInject.java index 96b1228de4..a91d76bc38 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestInject.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestInject.java @@ -147,7 +147,7 @@ import org.apache.juneau.svl.*; * </p> * <ol> * <li><b>Overriding-parent bean store</b> — Spring beans (in <c>juneau-rest-server-springboot</c> deployments, - * via <c>SpringBeanStore</c>), or any bean reachable through the configured overriding-parent + * via <c>SpringBeanStore2</c>), or any bean reachable through the configured overriding-parent * bean-store chain.</li> * <li><b>{@code @RestInject} method/field on the resource class</b> — registered as a regular bean-store * entry, beating the framework default.</li> diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/springboot/SpringBeanStore_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/springboot/SpringBeanStore_Test.java deleted file mode 100644 index 9b5d4d05c9..0000000000 --- a/juneau-utest/src/test/java/org/apache/juneau/rest/springboot/SpringBeanStore_Test.java +++ /dev/null @@ -1,178 +0,0 @@ -// *************************************************************************************************************************** -// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * -// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * -// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * -// * with the License. You may obtain a copy of the License at * -// * * -// * http://www.apache.org/licenses/LICENSE-2.0 * -// * * -// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * -// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * -// * specific language governing permissions and limitations under the License. * -// *************************************************************************************************************************** -package org.apache.juneau.rest.springboot; - -import static org.apache.juneau.commons.utils.Utils.*; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; - -import org.apache.juneau.*; -import org.junit.jupiter.api.*; -import org.springframework.beans.factory.*; -import org.springframework.context.*; - -/** - * Tests for SpringBeanStore fluent setter overrides. - */ -@SuppressWarnings({ - "unchecked" // Mockito generic type warnings -}) -class SpringBeanStore_Test extends TestBase { - - static class TestService { - private final String name; - TestService(String name) { this.name = name; } - @Override public String toString() { return "TestService[" + name + "]"; } - } - - @Test - void a01_fluentChaining_clear() { - var store = new SpringBeanStore(opte(), opte(), null); - - SpringBeanStore result = store.clear(); - - assertSame(store, result); - assertInstanceOf(SpringBeanStore.class, result); - } - - @Test - void b01_getBean_noAppContext_notFound() { - var store = new SpringBeanStore(opte(), opte(), null); - - var result = store.getBean(TestService.class); - - assertFalse(result.isPresent()); - } - - @Test - void b02_getBean_fromLocalStore() { - var store = new SpringBeanStore(opte(), opte(), null); - var service = new TestService("local"); - store.addBean(TestService.class, service); - - var result = store.getBean(TestService.class); - - assertTrue(result.isPresent()); - assertSame(service, result.get()); - } - - @Test - void b03_getBean_fromSpringContext() { - var mockAppContext = mock(ApplicationContext.class); - var service = new TestService("spring"); - var provider = mock(ObjectProvider.class); - when(mockAppContext.getBeanProvider(TestService.class)).thenReturn(provider); - when(provider.getIfAvailable()).thenReturn(service); - - var store = new SpringBeanStore(opt(mockAppContext), opte(), null); - var result = store.getBean(TestService.class); - - assertTrue(result.isPresent()); - assertSame(service, result.get()); - } - - @Test - void b04_getBean_springReturnsNull() { - var mockAppContext = mock(ApplicationContext.class); - var provider = mock(ObjectProvider.class); - when(mockAppContext.getBeanProvider(TestService.class)).thenReturn(provider); - when(provider.getIfAvailable()).thenReturn(null); - - var store = new SpringBeanStore(opt(mockAppContext), opte(), null); - var result = store.getBean(TestService.class); - - assertFalse(result.isPresent()); - } - - @Test - void b05_getBean_springThrowsException() { - var mockAppContext = mock(ApplicationContext.class); - when(mockAppContext.getBeanProvider(TestService.class)).thenThrow(new RuntimeException("Error")); - - var store = new SpringBeanStore(opt(mockAppContext), opte(), null); - var result = store.getBean(TestService.class); - - assertFalse(result.isPresent()); - } - - @Test - void c01_getBeanNamed_noAppContext_notFound() { - var store = new SpringBeanStore(opte(), opte(), null); - - var result = store.getBean(TestService.class, "myBean"); - - assertFalse(result.isPresent()); - } - - @Test - void c02_getBeanNamed_fromLocalStore() { - var store = new SpringBeanStore(opte(), opte(), null); - var service = new TestService("local"); - store.addBean(TestService.class, service, "myBean"); - - var result = store.getBean(TestService.class, "myBean"); - - assertTrue(result.isPresent()); - assertSame(service, result.get()); - } - - @Test - void c03_getBeanNamed_withNameFromSpring() { - var mockAppContext = mock(ApplicationContext.class); - var service = new TestService("spring"); - when(mockAppContext.containsBean("myBean")).thenReturn(true); - when(mockAppContext.getBean("myBean", TestService.class)).thenReturn(service); - - var store = new SpringBeanStore(opt(mockAppContext), opte(), null); - var result = store.getBean(TestService.class, "myBean"); - - assertTrue(result.isPresent()); - assertSame(service, result.get()); - } - - @Test - void c04_getBeanNamed_nameNotInSpring() { - var mockAppContext = mock(ApplicationContext.class); - when(mockAppContext.containsBean("myBean")).thenReturn(false); - when(mockAppContext.getBean(TestService.class)).thenReturn(null); - - var store = new SpringBeanStore(opt(mockAppContext), opte(), null); - var result = store.getBean(TestService.class, "myBean"); - - assertFalse(result.isPresent()); - } - - @Test - void c05_getBeanNamed_nullName_fromSpring() { - var mockAppContext = mock(ApplicationContext.class); - var service = new TestService("spring"); - when(mockAppContext.getBean(TestService.class)).thenReturn(service); - - var store = new SpringBeanStore(opt(mockAppContext), opte(), null); - var result = store.getBean(TestService.class, null); - - assertTrue(result.isPresent()); - assertSame(service, result.get()); - } - - @Test - void c06_getBeanNamed_springThrowsException() { - var mockAppContext = mock(ApplicationContext.class); - when(mockAppContext.containsBean("myBean")).thenThrow(new RuntimeException("Error")); - - var store = new SpringBeanStore(opt(mockAppContext), opte(), null); - var result = store.getBean(TestService.class, "myBean"); - - assertFalse(result.isPresent()); - } -} \ No newline at end of file diff --git a/todo/TODO-15-replace-basicbeanstore-with-v2.md b/todo/TODO-15-replace-basicbeanstore-with-v2.md index 15cc5fb8e3..c58b0202a7 100644 --- a/todo/TODO-15-replace-basicbeanstore-with-v2.md +++ b/todo/TODO-15-replace-basicbeanstore-with-v2.md @@ -161,7 +161,7 @@ Remaining inventory work: - [ ] **Retire remaining `BeanCreator.of(...)` memoizers.** — punted to **TODO-25**. Six holdouts in `RestContext` (`callLogger`, `debugEnablement`, `staticFiles`, `swaggerProvider`, the user-child-resource `BeanCreator.of(rc2, ...)` path, and `findRestOperationArgs`) plus `RestOpContext.createPartSerializer`. All six call sites already cast-free (via the `BeanCreator.of(Class, BeanStore)` overload landed 2026-05-08). Migration to `BeanInstantiator` blocked on `Basic*.init(BeanStore)` ze [...] - [ ] Migrate `McpPage` / `McpTypedHandlers` / `McpEndpoint` / `McpRestServlet` in `rest-server-mcp`. - [ ] Migrate remaining `juneau-microservice-*` / `juneau-config` consumers (if any). -- [ ] Update Javadoc-only references in `RestInject.java`, `RestInit.java`, `Name.java`, `Named.java`, `HttpPartParser.java`, `HttpPartSerializer.java`. +- ~~Update Javadoc-only references in `RestInject.java`, `RestInit.java`, `Name.java`, `Named.java`, `HttpPartParser.java`, `HttpPartSerializer.java`.~~ — **DONE / N/A (2026-05-08).** Survey shows `RestInject`, `RestInit`, `Name`, `Named` carry zero legacy references (cleaned up earlier — TODO entry was stale). `HttpPartParser` / `HttpPartSerializer` still extend legacy `ContextBeanCreator` (real code, not Javadoc) — gated on the Phase-4 `ContextBeanCreator` migration. - [ ] Migrate each public API surface in `juneau-marshall`. Since 9.5 allows simple breaking changes, replace rather than overload — document each signature change in the 9.5 release notes. ## Phase 4 — Cutover rename
