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
proxyBeanMethodsflag is set tofalsein 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. @Beanmethods 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
Optional ElementsModifier and TypeOptional ElementDescriptionbooleanSpecify whether@Beanmethods should get proxied in order to enforce bean lifecycle behavior, e.g.Explicitly specify the name of the Spring bean definition associated with the@Configurationclass.
-
Element Details
-
value
Explicitly specify the name of the Spring bean definition associated with the@Configurationclass. If left unspecified (the common case), a bean name will be automatically generated.The custom name applies only if the
@Configurationclass is picked up via component scanning or supplied directly to anAnnotationConfigApplicationContext. If the@Configurationclass 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@Beanmethods should get proxied in order to enforce bean lifecycle behavior, e.g. to return shared singleton bean instances even in case of direct@Beanmethod 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@Beanmethods, e.g. from another configuration class. If this is not needed since each of this particular configuration's@Beanmethods is self-contained and designed as a plain factory method for container use, switch this flag tofalsein order to avoid CGLIB subclass processing.Turning off bean method interception effectively processes
@Beanmethods individually like when declared on non-@Configurationclasses, a.k.a. "@Bean Lite Mode" (see@Bean's javadoc). It is therefore behaviorally equivalent to removing the@Configurationstereotype.- Since:
- 5.2
- Default:
- true
-