////
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.
////


==== Using the Spring Bean DSL


You can easily register new (or override existing) beans by configuring them in `grails-app/conf/spring/resources.groovy` which uses the Grails <<springdsl,Spring DSL>>. Beans are defined inside a `beans` property (a Closure):

[source,groovy]
----
beans = {
    // beans here
}
----

As a simple example you can configure a bean with the following syntax:

[source,groovy]
----
import my.company.MyBeanImpl

beans = {
    myBean(MyBeanImpl) {
        someProperty = 42
        otherProperty = "blue"
    }
}
----

Once configured, the bean can be auto-wired into Grails artifacts and other classes that support dependency injection (for example `BootStrap.groovy` and integration tests) by declaring a public field whose name is your bean's name (in this case `myBean`):

[source,groovy]
----
class ExampleController {

     def myBean
     ...
}
----

Using the DSL has the advantage that you can mix bean declarations and logic, for example based on the link:conf.html#environments[environment]:

[source,groovy]
----
import grails.util.Environment
import my.company.mock.MockImpl
import my.company.MyBeanImpl

beans = {
    switch(Environment.current) {
        case Environment.PRODUCTION:
            myBean(MyBeanImpl) {
                someProperty = 42
                otherProperty = "blue"
            }
            break

        case Environment.DEVELOPMENT:
            myBean(MockImpl) {
                someProperty = 42
                otherProperty = "blue"
            }
            break
    }
}
----

The `GrailsApplication` object can be accessed with the `application` variable and can be used to access the Grails configuration (amongst other things):

[source,groovy]
----
import grails.util.Environment
import my.company.mock.MockImpl
import my.company.MyBeanImpl

beans = {
    if (application.config.getProperty('my.company.mockService')) {
        myBean(MockImpl) {
            someProperty = 42
            otherProperty = "blue"
        }
    } else {
        myBean(MyBeanImpl) {
            someProperty = 42
            otherProperty = "blue"
        }
    }
}
----

NOTE: If you define a bean in `resources.groovy` with the same name as one previously registered by Grails or an installed plugin, your bean will replace the previous registration. This is a convenient way to customize behavior without resorting to editing plugin code or other approaches that would affect maintainability.


==== Using XML


Beans can also be configured using a `grails-app/conf/spring/resources.xml`. In earlier versions of Grails this file was automatically generated for you by the `run-app` script, but the DSL in `resources.groovy` is the preferred approach now so it isn't automatically generated now. But it is still supported - you just need to create it yourself.

This file is typical Spring XML file and the Spring documentation has an {springreference}core/beans/introduction.html[excellent reference] on how to configure Spring beans.

The `myBean` bean that we configured using the DSL would be configured with this syntax in the XML file:

[source,xml]
----
<bean id="myBean" class="my.company.MyBeanImpl">
    <property name="someProperty" value="42" />
    <property name="otherProperty" value="blue" />
</bean>
----

Like the other bean it can be auto-wired into any class that supports dependency injection:

[source,groovy]
----
class ExampleController {

     def myBean
}
----


==== Referencing Existing Beans


Beans declared in `resources.groovy` or `resources.xml` can reference other beans by convention. For example if you had a `BookService` class its Spring bean name would be `bookService`, so your bean would reference it like this in the DSL:

[source,groovy]
----
beans = {
    myBean(MyBeanImpl) {
        someProperty = 42
        otherProperty = "blue"
        bookService = ref("bookService")
    }
}
----

or like this in XML:

[source,xml]
----
<bean id="myBean" class="my.company.MyBeanImpl">
    <property name="someProperty" value="42" />
    <property name="otherProperty" value="blue" />
    <property name="bookService" ref="bookService" />
</bean>
----

The bean needs a public setter for the bean reference (and also the two simple properties), which in Groovy would be defined like this:

[source,groovy]
----
package my.company

class MyBeanImpl {
    Integer someProperty
    String otherProperty
    BookService bookService
}
----

or in Java like this:

[source,groovy]
----
package my.company;

class MyBeanImpl {

    private BookService bookService;
    private Integer someProperty;
    private String otherProperty;

    public void setBookService(BookService theBookService) {
        this.bookService = theBookService;
    }

    public void setSomeProperty(Integer someProperty) {
        this.someProperty = someProperty;
    }

    public void setOtherProperty(String otherProperty) {
        this.otherProperty = otherProperty;
    }
}
----

Using `ref` (in XML or the DSL) is very powerful since it configures a runtime reference, so the referenced bean doesn't have to exist yet. As long as it's in place when the final application context configuration occurs, everything will be resolved correctly.

For a full reference of the available beans see the plugin reference in the reference guide.


==== Defining Beans at Compile Time with @GrailsBeans


`resources.groovy` and `doWithSpring` wire their beans at runtime, every time the application starts. The link:{api}grails/compiler/beans/GrailsBeans.html[GrailsBeans] annotation is a compile-time alternative: a similar closure style of bean definition, compiled at build time into real `@Bean` factory methods — no closures, and nothing DSL-specific, survive into the bytecode.

`@GrailsBeans` is not plugin-specific. It works on any class Spring Boot processes as a configuration source — including the application's own `Application` class, since Spring Boot reads `@Bean` methods directly off the class it is launched with. Declare a `beans` closure whose statements construct and return each bean:

[source,groovy]
----
import grails.boot.GrailsApp
import grails.boot.config.GrailsAutoConfiguration
import my.company.MyBeanImpl

class Application extends GrailsAutoConfiguration {

    static void main(String[] args) {
        GrailsApp.run(Application, args)
    }

    def beans = {
        bean(MyService)

        bean('myBean', MyBeanImpl) {
            new MyBeanImpl(someProperty: 42, otherProperty: 'blue')
        }
    }
}
----

Both the name and the body are optional. `bean(MyService)` declares a bean named `myService` — the type's decapitalized simple name — that is simply `new MyService()`; give it a name only when the type does not produce the one you want, and a body only when there is something to say beyond constructing it.

No annotation is required on the `Application` class, or on a `*GrailsPlugin.groovy` plugin descriptor: a `beans` property on either is compiled automatically, in the same way `doWithSpring` and `watchedResources` are conventions rather than annotated members. `@GrailsBeans` is only needed on a class that is neither — a standalone `@AutoConfiguration` class, which must also be listed in `META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports` like any other hand-written auto-configuration. Declaring the annotation explicitly on a plugin or application class is harmless, and a class with no `beans` property is left entirely alone.

No further registration is needed on the `Application` class — Spring Boot already processes it. Beans declared here are also ordinary user beans as far as Spring Boot is concerned, so any auto-configuration guarded by `@ConditionalOnMissingBean` backs off in their favour, exactly as it would for a bean defined in `resources.groovy`. A standalone class annotated with both `@GrailsBeans` and `@AutoConfiguration` must instead be listed in `META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports`, like any other hand-written auto-configuration.

The DSL's full surface — the `bean(...)` qualifiers such as `.conditionalOnMissingBean(...)`, `.primary()` and `.annotate(...)`, plus `field(...)` and `method(...)` for state and logic shared across bean methods — is documented in the link:plugins.html#hookingIntoRuntimeConfiguration[plugin development chapter], together with applying `@GrailsBeans` directly to a plugin descriptor.
