This is an automated email from the ASF dual-hosted git repository. jamesfredley pushed a commit to branch feat/beanbuilder-beanregistry-seed in repository https://gitbox.apache.org/repos/asf/grails-core.git
commit ea082c63a2c1951f6a99c69bfb1dc075502021ca Author: James Fredley <[email protected]> AuthorDate: Fri Jul 10 12:57:49 2026 -0400 Seed BeanRegistry adapter over BeanBuilder Add experimental BeanRegistryAdapter that still uses BeanBuilder while documenting Spring 7 BeanRegistrar path. Assisted-by: Sisyphus:xai/grok-4.5 [gpt-coding] --- grails-doc/src/en/guide/toc.yml | 1 + .../en/guide/upgrading/beanRegistryAdapter.adoc | 7 +++ grails-spring/build.gradle | 3 +- .../spring/BeanBuilderBeanRegistryAdapter.java | 64 ++++++++++++++++++++++ .../groovy/grails/spring/BeanRegistryAdapter.java | 40 ++++++++++++++ .../BeanBuilderBeanRegistryAdapterTest.groovy | 48 ++++++++++++++++ 6 files changed, 162 insertions(+), 1 deletion(-) diff --git a/grails-doc/src/en/guide/toc.yml b/grails-doc/src/en/guide/toc.yml index b0e4a5c3ff..f783ee83fc 100644 --- a/grails-doc/src/en/guide/toc.yml +++ b/grails-doc/src/en/guide/toc.yml @@ -37,6 +37,7 @@ gettingStarted: upgrading: title: Upgrading from the previous versions upgrading80x: Upgrading from Grails 7 to Grails 8 + beanRegistryAdapter: BeanBuilder to BeanRegistry strategy upgrading72x: Upgrading from Grails 7.1 to Grails 7.2 upgrading71x: Upgrading from Grails 7.0 to Grails 7.1 upgrading70x: Upgrading from Grails 6 to Grails 7.0 diff --git a/grails-doc/src/en/guide/upgrading/beanRegistryAdapter.adoc b/grails-doc/src/en/guide/upgrading/beanRegistryAdapter.adoc new file mode 100644 index 0000000000..fccc0f36df --- /dev/null +++ b/grails-doc/src/en/guide/upgrading/beanRegistryAdapter.adoc @@ -0,0 +1,7 @@ +=== BeanBuilder to BeanRegistry strategy + +Grails 8.1 introduces an experimental `grails.spring.BeanRegistryAdapter` seam as the first step toward the Spring 7 `BeanRegistrar` direction tracked in issue #15824. +The initial `BeanBuilderBeanRegistryAdapter` delegates to the existing `BeanBuilder`, so `resources.groovy`, plugin `doWithSpring`, and existing BeanBuilder APIs continue to work unchanged. + +The intended migration path is to move call sites behind the adapter first, then add a Spring 7 BeanRegistrar-backed implementation once the framework integration points are ready. +BeanBuilder is not removed or behaviorally changed by this seed. diff --git a/grails-spring/build.gradle b/grails-spring/build.gradle index e0aaa04a5b..3e813cf6b9 100644 --- a/grails-spring/build.gradle +++ b/grails-spring/build.gradle @@ -62,4 +62,5 @@ dependencies { apply { from rootProject.layout.projectDirectory.file('gradle/docs-config.gradle') -} \ No newline at end of file + from rootProject.layout.projectDirectory.file('gradle/test-config.gradle') +} diff --git a/grails-spring/src/main/groovy/grails/spring/BeanBuilderBeanRegistryAdapter.java b/grails-spring/src/main/groovy/grails/spring/BeanBuilderBeanRegistryAdapter.java new file mode 100644 index 0000000000..614e52de2e --- /dev/null +++ b/grails-spring/src/main/groovy/grails/spring/BeanBuilderBeanRegistryAdapter.java @@ -0,0 +1,64 @@ +/* + * 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 + * + * 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 grails.spring; + +import java.util.Map; + +import groovy.lang.Closure; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; + +/** + * BeanRegistryAdapter backed by the existing BeanBuilder implementation. + * + * @since 8.1 + */ +public class BeanBuilderBeanRegistryAdapter implements BeanRegistryAdapter { + + private final BeanBuilder beanBuilder; + + public BeanBuilderBeanRegistryAdapter() { + this(new BeanBuilder()); + } + + public BeanBuilderBeanRegistryAdapter(BeanBuilder beanBuilder) { + this.beanBuilder = beanBuilder; + } + + public BeanBuilder getBeanBuilder() { + return beanBuilder; + } + + @Override + public BeanRegistryAdapter beans(Closure<?> closure) { + beanBuilder.beans(closure); + return this; + } + + @Override + public Map<String, BeanDefinition> getBeanDefinitions() { + return beanBuilder.getBeanDefinitions(); + } + + @Override + public void registerBeans(BeanDefinitionRegistry registry) { + beanBuilder.registerBeans(registry); + } +} diff --git a/grails-spring/src/main/groovy/grails/spring/BeanRegistryAdapter.java b/grails-spring/src/main/groovy/grails/spring/BeanRegistryAdapter.java new file mode 100644 index 0000000000..51b2ada429 --- /dev/null +++ b/grails-spring/src/main/groovy/grails/spring/BeanRegistryAdapter.java @@ -0,0 +1,40 @@ +/* + * 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 + * + * 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 grails.spring; + +import java.util.Map; + +import groovy.lang.Closure; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; + +/** + * Experimental adapter seam for the BeanBuilder to Spring BeanRegistrar transition. + * + * @since 8.1 + */ +public interface BeanRegistryAdapter { + + BeanRegistryAdapter beans(Closure<?> closure); + + Map<String, BeanDefinition> getBeanDefinitions(); + + void registerBeans(BeanDefinitionRegistry registry); +} diff --git a/grails-spring/src/test/groovy/grails/spring/BeanBuilderBeanRegistryAdapterTest.groovy b/grails-spring/src/test/groovy/grails/spring/BeanBuilderBeanRegistryAdapterTest.groovy new file mode 100644 index 0000000000..4dd514b067 --- /dev/null +++ b/grails-spring/src/test/groovy/grails/spring/BeanBuilderBeanRegistryAdapterTest.groovy @@ -0,0 +1,48 @@ +/* + * 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 + * + * 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 grails.spring + +import org.junit.jupiter.api.Test + +import org.springframework.context.support.GenericApplicationContext + +import static org.junit.jupiter.api.Assertions.assertEquals +import static org.junit.jupiter.api.Assertions.assertTrue + +class BeanBuilderBeanRegistryAdapterTest { + + @Test + void adapterRegistersBeansThroughExistingBeanBuilderPath() { + BeanRegistryAdapter adapter = new BeanBuilderBeanRegistryAdapter() + GenericApplicationContext applicationContext = new GenericApplicationContext() + try { + adapter.beans { + sampleBean(String, 'adapter') + } + adapter.registerBeans(applicationContext) + applicationContext.refresh() + + assertTrue(adapter.beanDefinitions.containsKey('sampleBean')) + assertEquals('adapter', applicationContext.getBean('sampleBean')) + } + finally { + applicationContext.close() + } + } +}
