Annotation Interface Configuration
@Bean
methods and
may be processed by the Spring container to generate bean definitions and
service requests for those beans at runtime, for example:
@Configuration public class AppConfig { @Bean public MyBean myBean() { // instantiate, configure and return bean ... } }
Bootstrapping @Configuration
classes
Via AnnotationConfigApplicationContext
@Configuration
classes are typically bootstrapped using either
AnnotationConfigApplicationContext
or its web-capable variant,
AnnotationConfigWebApplicationContext
. A simple example with the former follows:
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(AppConfig.class); ctx.refresh(); MyBean myBean = ctx.getBean(MyBean.class); // use myBean ...
See the AnnotationConfigApplicationContext
javadocs for further details, and see
AnnotationConfigWebApplicationContext
for web configuration instructions in a
Servlet
container.
Via Spring <beans>
XML
As an alternative to registering @Configuration
classes directly against an
AnnotationConfigApplicationContext
, @Configuration
classes may be
declared as normal <bean>
definitions within Spring XML files:
<beans> <context:annotation-config/> <bean class="com.acme.AppConfig"/> </beans>
In the example above, <context:annotation-config/>
is required in order to
enable ConfigurationClassPostProcessor
and other annotation-related
post processors that facilitate handling @Configuration
classes.
Via component scanning
@Configuration
is meta-annotated with @Component
, therefore
@Configuration
classes are candidates for component scanning (typically using
Spring XML's <context:component-scan/>
element) and therefore may also take
advantage of @Autowired
/@Inject
like any regular @Component
. In particular, if a single constructor is present
autowiring semantics will be applied transparently for that constructor:
@Configuration public class AppConfig { private final SomeBean someBean; public AppConfig(SomeBean someBean) { this.someBean = someBean; } // @Bean definition using "SomeBean" }
@Configuration
classes may not only be bootstrapped using
component scanning, but may also themselves configure component scanning using
the @ComponentScan
annotation:
@Configuration @ComponentScan("com.acme.app.services") public class AppConfig { // various @Bean definitions ... }
See the @ComponentScan
javadocs for details.
Working with externalized values
Using the Environment
API
Externalized values may be looked up by injecting the Spring
Environment
into a @Configuration
class — for example, using the @Autowired
annotation:
@Configuration public class AppConfig { @Autowired Environment env; @Bean public MyBean myBean() { MyBean myBean = new MyBean(); myBean.setName(env.getProperty("bean.name")); return myBean; } }
Properties resolved through the Environment
reside in one or more "property
source" objects, and @Configuration
classes may contribute property sources to
the Environment
object using the @PropertySource
annotation:
@Configuration @PropertySource("classpath:/com/acme/app.properties") public class AppConfig { @Inject Environment env; @Bean public MyBean myBean() { return new MyBean(env.getProperty("bean.name")); } }
See the Environment
and @PropertySource
javadocs for further details.
Using the @Value
annotation
Externalized values may be injected into @Configuration
classes using
the @Value
annotation:
@Configuration @PropertySource("classpath:/com/acme/app.properties") public class AppConfig { @Value("${bean.name}") String beanName; @Bean public MyBean myBean() { return new MyBean(beanName); } }
This approach is often used in conjunction with Spring's
PropertySourcesPlaceholderConfigurer
that can be enabled automatically
in XML configuration via <context:property-placeholder/>
or explicitly
in a @Configuration
class via a dedicated static
@Bean
method
(see "a note on BeanFactoryPostProcessor-returning @Bean
methods" of
@Bean
's javadocs for details). Note, however, that explicit registration
of a PropertySourcesPlaceholderConfigurer
via a static
@Bean
method is typically only required if you need to customize configuration such as the
placeholder syntax, etc. Specifically, if no bean post-processor (such as a
PropertySourcesPlaceholderConfigurer
) has registered an embedded value
resolver for the ApplicationContext
, Spring will register a default
embedded value resolver which resolves placeholders against property sources
registered in the Environment
. See the section below on composing
@Configuration
classes with Spring XML using @ImportResource
; see
the @Value
javadocs; and see the @Bean
javadocs for details
on working with BeanFactoryPostProcessor
types such as
PropertySourcesPlaceholderConfigurer
.
Composing @Configuration
classes
With the @Import
annotation
@Configuration
classes may be composed using the @Import
annotation,
similar to the way that <import>
works in Spring XML. Because
@Configuration
objects are managed as Spring beans within the container,
imported configurations may be injected — for example, via constructor injection:
@Configuration public class DatabaseConfig { @Bean public DataSource dataSource() { // instantiate, configure and return DataSource } } @Configuration @Import(DatabaseConfig.class) public class AppConfig { private final DatabaseConfig dataConfig; public AppConfig(DatabaseConfig dataConfig) { this.dataConfig = dataConfig; } @Bean public MyBean myBean() { // reference the dataSource() bean method return new MyBean(dataConfig.dataSource()); } }
Now both AppConfig
and the imported DatabaseConfig
can be bootstrapped
by registering only AppConfig
against the Spring context:
new AnnotationConfigApplicationContext(AppConfig.class);
With the @Profile
annotation
@Configuration
classes may be marked with the @Profile
annotation to
indicate they should be processed only if a given profile or profiles are active:
@Profile("development") @Configuration public class EmbeddedDatabaseConfig { @Bean public DataSource dataSource() { // instantiate, configure and return embedded DataSource } } @Profile("production") @Configuration public class ProductionDatabaseConfig { @Bean public DataSource dataSource() { // instantiate, configure and return production DataSource } }
Alternatively, you may also declare profile conditions at the @Bean
method level
— for example, for alternative bean variants within the same configuration class:
@Configuration public class ProfileDatabaseConfig { @Bean("dataSource") @Profile("development") public DataSource embeddedDatabase() { ... } @Bean("dataSource") @Profile("production") public DataSource productionDatabase() { ... } }
See the @Profile
and Environment
javadocs for further details.
With Spring XML using the @ImportResource
annotation
As mentioned above, @Configuration
classes may be declared as regular Spring
<bean>
definitions within Spring XML files. It is also possible to
import Spring XML configuration files into @Configuration
classes using
the @ImportResource
annotation. Bean definitions imported from
XML can be injected — for example, using the @Inject
annotation:
@Configuration @ImportResource("classpath:/com/acme/database-config.xml") public class AppConfig { @Inject DataSource dataSource; // from XML @Bean public MyBean myBean() { // inject the XML-defined dataSource bean return new MyBean(this.dataSource); } }
With nested @Configuration
classes
@Configuration
classes may be nested within one another as follows:
@Configuration public class AppConfig { @Inject DataSource dataSource; @Bean public MyBean myBean() { return new MyBean(dataSource); } @Configuration static class DatabaseConfig { @Bean DataSource dataSource() { return new EmbeddedDatabaseBuilder().build(); } } }
When bootstrapping such an arrangement, only AppConfig
need be registered
against the application context. By virtue of being a nested @Configuration
class, DatabaseConfig
will be registered automatically. This avoids
the need to use an @Import
annotation when the relationship between
AppConfig
and DatabaseConfig
is already implicitly clear.
Note also that nested @Configuration
classes can be used to good effect
with the @Profile
annotation to provide two options of the same bean to the
enclosing @Configuration
class.
Configuring lazy initialization
By default, @Bean
methods will be eagerly instantiated at container
bootstrap time. To avoid this, @Configuration
may be used in conjunction with
the @Lazy
annotation to indicate that all @Bean
methods declared
within the class are by default lazily initialized. Note that @Lazy
may be used
on individual @Bean
methods as well.
Testing support for @Configuration
classes
The Spring TestContext framework available in the spring-test
module
provides the @ContextConfiguration
annotation which can accept an array of
component class references — typically @Configuration
or
@Component
classes.
@RunWith(SpringRunner.class) @ContextConfiguration(classes = {AppConfig.class, DatabaseConfig.class}) public class MyTests { @Autowired MyBean myBean; @Autowired DataSource dataSource; @Test public void test() { // assertions against myBean ... } }
See the TestContext framework reference documentation for details.
Enabling built-in Spring features using @Enable
annotations
Spring features such as asynchronous method execution, scheduled task execution,
annotation driven transaction management, and even Spring MVC can be enabled and
configured from @Configuration
classes using their respective "@Enable
"
annotations. See
@EnableAsync
,
@EnableScheduling
,
@EnableTransactionManagement
,
@EnableAspectJAutoProxy
,
and @EnableWebMvc
for details.
Constraints when authoring @Configuration
classes
- Configuration classes must be provided as classes (i.e. not as instances returned from factory methods), allowing for runtime enhancements through a generated subclass.
- Configuration classes must be non-final (allowing for subclasses at runtime),
unless the
proxyBeanMethods
flag is set tofalse
in which case no runtime-generated subclass is necessary. - Configuration classes must be non-local (i.e. may not be declared within a method).
- Any nested configuration classes must be declared as
static
. @Bean
methods may not in turn create further configuration classes (any such instances will be treated as regular beans, with their configuration annotations remaining undetected).
- Since:
- 3.0
- Author:
- Rod Johnson, Chris Beams, Juergen Hoeller
- See Also:
-
Optional Element Summary
Modifier and TypeOptional ElementDescriptionboolean
Specify whether@Bean
methods should get proxied in order to enforce bean lifecycle behavior, e.g.Explicitly specify the name of the Spring bean definition associated with the@Configuration
class.
-
Element Details
-
value
Explicitly specify the name of the Spring bean definition associated with the@Configuration
class. If left unspecified (the common case), a bean name will be automatically generated.The custom name applies only if the
@Configuration
class is picked up via component scanning or supplied directly to anAnnotationConfigApplicationContext
. If the@Configuration
class is registered as a traditional XML bean definition, the name/id of the bean element will take precedence.- Returns:
- the explicit component name, if any (or empty String otherwise)
- See Also:
- Default:
- ""
-
proxyBeanMethods
boolean proxyBeanMethodsSpecify whether@Bean
methods should get proxied in order to enforce bean lifecycle behavior, e.g. to return shared singleton bean instances even in case of direct@Bean
method calls in user code. This feature requires method interception, implemented through a runtime-generated CGLIB subclass which comes with limitations such as the configuration class and its methods not being allowed to declarefinal
.The default is
true
, allowing for 'inter-bean references' via direct method calls within the configuration class as well as for external calls to this configuration's@Bean
methods, e.g. from another configuration class. If this is not needed since each of this particular configuration's@Bean
methods is self-contained and designed as a plain factory method for container use, switch this flag tofalse
in order to avoid CGLIB subclass processing.Turning off bean method interception effectively processes
@Bean
methods individually like when declared on non-@Configuration
classes, a.k.a. "@Bean Lite Mode" (see@Bean's javadoc
). It is therefore behaviorally equivalent to removing the@Configuration
stereotype.- Since:
- 5.2
- Default:
- true
-