codeconsole opened a new pull request, #16019:
URL: https://github.com/apache/grails-core/pull/16019

   ## Summary
   
   This is a proof-of-concept / discussion-stage spike, **not a request to 
merge as-is**. It explores whether Grails-authored bean wiring can get 
`doWithSpring()`-style DSL ergonomics while compiling down to a genuine Spring 
Boot `@AutoConfiguration` class — no closures, no custom runtime, nothing but 
real `@Bean` methods in the compiled bytecode.
   
   Two pieces:
   
   1. **`grails-beans-dsl`** — a `@GrailsBeans` annotation + local Groovy AST 
transformation (`GrailsBeansASTTransformation`) that rewrites a `beans = { 
bean(Type[, "name"]) { ... } }` closure into public `@Bean` factory methods, 
with `.conditionalOnMissingBean(Type...)` chaining and typed closure parameters 
becoming constructor-style-injected method parameters.
   2. **`org.apache.grails.buildsrc.autoconfiguration-imports`** — a new 
build-logic convention plugin that generates 
`META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports`
 by scanning a module's own compiled classes for `@AutoConfiguration`, the same 
way `META-INF/grails-plugin.xml` is already generated from scanned 
`*GrailsPlugin` classes elsewhere in this build — so the imports file never has 
to be hand-maintained.
   
   ## Why this, given `beanRegistrar()` already exists
   
   `Plugin.beanRegistrar()` (#15994) plus the before-autoconfiguration retiming 
(#15934) already give Grails a Spring-native, statically-compilable 
bean-registration mechanism that runs before Boot evaluates its 
`@ConditionalOnMissingBean` defaults. That solves the *coarse* half of what 
this spike targets.
   
   It does **not** solve the *fine-grained* half: `beanRegistrar()` output is 
inserted as a single hard cut point ahead of *all* Boot auto-configuration, 
ordered only relative to other Grails plugins by name — it has no way to 
express "run before this specific `@AutoConfiguration` but after that one," the 
way `@AutoConfiguration(before = ..., after = ...)` lets a real 
autoconfiguration class do against *any* other autoconfiguration on the 
classpath, Grails-authored or third-party. That's the open question this spike 
is raising: is it worth Grails-authored beans compiling down to genuine 
`@AutoConfiguration` classes so they can fully participate in Boot's own 
ordering graph, with DSL ergonomics comparable to `beanRegistrar()`?
   
   ## Usage example
   
   Author:
   
   ```groovy
   package myapp
   
   import org.grails.compiler.beans.GrailsBeans
   import org.springframework.boot.autoconfigure.AutoConfiguration
   
   @GrailsBeans
   @AutoConfiguration
   class MyBeans {
       def beans = {
           bean(Greeter, 'greeter') {
               new Greeter('hello')
           }
   
           bean(FancyGreeter, 
'fancyGreeter').conditionalOnMissingBean(FancyGreeter) {
               new FancyGreeter()
           }
   
           bean(LoudGreeter, 'loudGreeter') { Greeter greeter ->
               new LoudGreeter(greeter)
           }
       }
   }
   ```
   
   Compiles to the equivalent of (verified directly via `javap` — zero closures 
survive into the bytecode):
   
   ```java
   @AutoConfiguration
   public class MyBeans {
       @Bean("greeter")
       public Greeter greeter() { return new Greeter("hello"); }
   
       @Bean("fancyGreeter")
       @ConditionalOnMissingBean(FancyGreeter.class)
       public FancyGreeter fancyGreeter() { return new FancyGreeter(); }
   
       @Bean("loudGreeter")
       public LoudGreeter loudGreeter(Greeter greeter) { return new 
LoudGreeter(greeter); }
   }
   ```
   
   Register it by applying the new convention plugin (see 
`grails-beans-dsl-example/build.gradle`):
   
   ```groovy
   plugins {
       id 'org.apache.grails.buildsrc.autoconfiguration-imports'
   }
   ```
   
   which scans the module's compiled output and writes 
`META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports`
 automatically at build time.
   
   
`grails-beans-dsl-example/src/test/groovy/beandsl/example/ExampleBeansAutoDiscoverySpec.groovy`
 is the end-to-end proof this actually works as a whole pipeline: it boots a 
bare `@EnableAutoConfiguration` application with **zero explicit reference** to 
`ExampleBeans`, and the beans are still discovered and correctly wired — purely 
from the generated imports file.
   
   ## What's here
   
   - `grails-beans-dsl` — the annotation + transform, with unit tests that 
compile fixture sources and inspect the generated bytecode directly.
   - `grails-beans-dsl-example` — a worked example (`Greeter` / `FancyGreeter` 
/ `LoudGreeter`), including the conditional-back-off test and the 
auto-discovery end-to-end test above.
   - `build-logic` — the new `autoconfiguration-imports` convention plugin, 
with its own fixture-compiling unit tests.
   
   ## Test plan
   
   - [x] `:grails-beans-dsl:test` — AST transform unit tests
   - [x] `:grails-beans-dsl-example:test` — conditional back-off + end-to-end 
classpath auto-discovery
   - [x] `:build-logic:test` / `:build-logic:check` — imports-generation task 
unit tests
   - [x] `checkstyleMain` / `codenarcMain` clean on all new source
   - [ ] Full-repo `aggregateViolations` / RAT / SBOM / doc-guide integration — 
deliberately **not** run; this is a discussion-stage spike, not merge-ready
   
   ## Deliberately not done yet (first-look spike)
   
   - No `grails-doc` guide chapter
   - DSL surface is intentionally narrow — single-type conditional only, no 
property values / destroy methods / parent bean definitions (comparable 
limitations to `BeanRegistry.Spec`)
   - Not reconciled with `beanRegistrar()` beyond the comparison above — 
looking for feedback on whether the fine-grained ordering capability is worth a 
second bean-wiring mechanism, or whether that capability should be added to 
`beanRegistrar()` / the plugin ordering system instead


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to