3. Using @Configuration classes
Prev |  | Next

## 3. Using `@Configuration` classes

## 3.1. Bootstrapping applications with `JavaConfigApplicationContext`

`JavaConfigApplicationContext` provides direct access to the beans defined by `@Configuration`-annotated classes. For more information on the `ApplicationContext` API in general, please refer to the Core Spring documentation.

### 3.1.1. Construction Options

Instantiating the `JavaConfigApplicationContext` can be done by supplying `@Configuration` class literals to the constructor, and/or strings representing packages to scan for `@Configuration` classes.

#### 3.1.1.1. Construction by class literal

Each of the class literals supplied to the constructor will be processed, and for each `@Bean` method encountered, JavaConfig will create a bean definition and ultimately instantiate and initialize the bean.

    JavaConfigApplicationContext context = new JavaConfigApplicationContext(AppConfig.class);
    Service service = context.getBean(Service.class);

Passing multiple `@Configuration` classes:

    JavaConfigApplicationContext context =
        new JavaConfigApplicationContext(AppConfig.class, DataConfig.class);
    Service service = context.getBean(Service.class);

#### 3.1.1.2. Construction by base package

Base packages will be scanned for the existence of any `@Configuration` classes. Any candidate classes will then be processed much as if they had been supplied directly as class literals to the constructor.

    JavaConfigApplicationContext context =
        new JavaConfigApplicationContext("com.acme.app.configuration");
    Service service = context.getBean(Service.class);

Passing multiple base packages:

    JavaConfigApplicationContext context =
        new JavaConfigApplicationContext("com.acme.configuration", "com.acme.other");
    Service service = context.getBean(Service.class);

Matching packages and classes by wildcard:

    JavaConfigApplicationContext context =
        new JavaConfigApplicationContext("**/configuration/**/*.class", "**/other/*Config.class");
    Service service = context.getBean(Service.class);

| Note
The wildcard syntax for matching packages and classes above is based on Ant Patterns

#### 3.1.1.3. Post-construction configuration

When one or more classes/packages are supplied as constructor arguments, a `JavaConfigApplicationContext` instance cannot be further configured. If post-construction configuration is preferred or required, use either the no-arg constructor, configure by calling setters, then manually refresh the context. After the call to `refresh()`, the context will be 'closed for configuration'.

    JavaConfigApplicationContext context = new JavaConfigApplicationContext();
    context.setParent(otherConfig);
    context.setConfigClasses(AppConfig.class, DataConfig.class);
    context.setBasePackages("com.acme.configuration");
    context.refresh();
    Service service = (Service) context.getBean("serviceA");

| Note
Whenever multiple packages and/or classes are used to instantiate a `JavaConfigApplicationContext`, order matters. This is important when considering what happens if two configuration classes define a bean with the same name. The last-specified class wins.

### 3.1.2. Accessing beans with `getBean()`

`JavaConfigApplicationContext` provides several variants of the `getBean()` method for accessing beans.

#### 3.1.2.1. Type-safe access

The preferred method for accessing beans is with the type-safe `getBean()` method.

    JavaConfigApplicationContext context = new JavaConfigApplicationContext(...);
    Service service = context.getBean(Service.class);

##### Disambuguation options

If more than one bean of type `Service` had been defined in the example above, the call to `getBean()` would have thrown an exception indicating an ambiguity that the container could not resolve. In these cases, the user has a number of options for disambiguation:

###### Indicating a `@Bean` as `primary`

Like Spring's XML configuration, JavaConfig allows for specifying a given `@Bean` as `primary`:

    @Configuration
    public class MyConfig {
        @Bean(primary=Primary.TRUE)
        public Service myService() {
            return new Service();
        }

        @Bean
        public Service backupService() {
            return new Service();
        }
    }

After this modification, all calls to `getBean(Service.class)` will return the `primary` bean

    JavaConfigApplicationContext context = new JavaConfigApplicationContext(...);
    Service service = context.getBean(Service.class); // returns the myService() primary bean

###### Disambiguation by bean name

JavaConfig provides a `getBean()` variant that accepts both a class and a bean name for cases just such as these.

    JavaConfigApplicationContext context = new JavaConfigApplicationContext(...);
    Service service = context.getBean(Service.class, "myService");

Because bean ids must be unique, this call guarantees that the ambiguity cannot occur.

###### Retrieve all beans of a given type

It is also reasonable to call the `getBeansOfType()` method in order to return all beans that implement a given interface:

    JavaConfigApplicationContext context = new JavaConfigApplicationContext(...);
    Map matchingBeans = context.getBeansOfType(Service.class);

Note that this latter approach is actually a feature of the Core Spring Framework's `AbstractApplicationContext` (which `JavaConfigApplicationContext` extends) and is not type-safe, in that the returned `Map` is not parameterized.

#### 3.1.2.2. String-based access

Beans may be accessed via the traditional string-based `getBean()` API as well. Of course this is not type-safe and requires casting, but avoids any potential ambiguity entirely:

    JavaConfigApplicationContext context = new JavaConfigApplicationContext(...);
    Service service = (Service) context.getBean("myService");

Prev |  | Next
2.2. @Bean | Home | 3.2. Bootstrapping web applications with JavaConfigWebApplicationContext