Annotation Interface Configuration
@Component methods and
may be processed by the container to generate bean definitions and
service requests for those beans at runtime, for example:
@Configuration
public class AppConfig {
@Component
public MyBean myBean() {
// instantiate, configure and return bean ...
}
}
Bootstrapping @Configuration classes
Via StandardApplicationContext
@Configuration classes are typically bootstrapped using either
AnnotationConfigApplicationContext or its web-capable variant,
StandardWebServletApplicationContext. A simple example with the former follows:
StandardApplicationContext ctx = new StandardApplicationContext(); 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 <beans> XML
As an alternative to registering @Configuration classes directly against an
StandardApplicationContext, @Configuration classes may be
declared as normal <bean> definitions within 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
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;
}
// @Component 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 @Component definitions ...
}
See the @ComponentScan javadocs for details.
Working with externalized values
Using the Environment API
Externalized values may be looked up by injecting the
Environment into a @Configuration
class — for example, using the @Autowired annotation:
@Configuration
public class AppConfig {
@Autowired Environment env;
@Component
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;
@Component
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;
@Component
public MyBean myBean() {
return new MyBean(beanName);
}
}
This approach is often used in conjunction with
PropertySourcesPlaceholderConfigurer that can be enabled automatically
in XML configuration via <context:property-placeholder/> or explicitly
in a @Configuration class via a dedicated static @Component method
(see "a note on BeanFactoryPostProcessor-returning @Component methods" of
@Component's javadocs for details).
Note, however, that explicit registration
of a PropertySourcesPlaceholderConfigurer via a static @Component
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, 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 XML using @ImportResource; see
the @Value javadocs; and see the @Component 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 @Import} annotation,
similar to the way that <import> works in XML. Because
@Configuration objects are managed as beans within the container,
imported configurations may be injected — for example, via constructor injection:
@Configuration
public class DatabaseConfig {
@Component
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;
}
@Component
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 context:
new StandardApplicationContext(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 {
@Component
public DataSource dataSource() {
// instantiate, configure and return embedded DataSource
}
}
@Profile("production")
@Configuration
public class ProductionDatabaseConfig {
@Component
public DataSource dataSource() {
// instantiate, configure and return production DataSource
}
}
Alternatively, you may also declare profile conditions at the @Component method level
— for example, for alternative bean variants within the same configuration class:
@Configuration
public class ProfileDatabaseConfig {
@Component("dataSource")
@Profile("development")
public DataSource embeddedDatabase() { ... }
@Component("dataSource")
@Profile("production")
public DataSource productionDatabase() { ... }
}
See the @Profile and Environment
javadocs for further details.
With nested @Configuration classes
@Configuration classes may be nested within one another as follows:
@Configuration
public class AppConfig {
@Inject DataSource dataSource;
@Component
public MyBean myBean() {
return new MyBean(dataSource);
}
@Configuration
static class DatabaseConfig {
@Component
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, @Component 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 @Component methods declared
within the class are by default lazily initialized. Note that @Lazy may be used
on individual @Component methods as well.
Testing support for @Configuration classes
The Framework TestContext framework available in the today-test module
provides the @ContextConfiguration annotation which can accept an array of
component class references — typically @Configuration or
@Component classes.
@RunWith(TODAYRunner.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 Framework features using @Enable annotations
Framework features such as asynchronous method execution, scheduled task execution,
annotation driven transaction management, and even Framework MVC can be enabled and
configured from @Configuration classes using their respective "@Enable"
annotations. See
@EnableAsync,
@EnableScheduling,
@EnableTransactionManagement,
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. @Componentmethods may not in turn create further configuration classes (any such instances will be treated as regular beans, with their configuration annotations remaining undetected).
- 从以下版本开始:
- 4.0
- 作者:
- Rod Johnson, Chris Beams, Juergen Hoeller, TODAY
2018-09-06 14:05 - 另请参阅:
-
可选元素概要
可选元素修饰符和类型可选元素说明booleanSpecify whether@Componentmethods should get proxied in order to enforce bean lifecycle behavior, e.g. to return shared singleton bean instances even in case of direct@Componentmethod calls in user code.String[]Explicitly specify the name of the Framework bean definition associated with the@Configurationclass.
-
元素详细资料
-
value
Explicitly specify the name of the Framework 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 anStandardApplicationContext. If the@Configurationclass is registered as a traditional XML bean definition, the name/id of the bean element will take precedence.- 返回:
- the explicit component name, if any (or empty String otherwise)
- 默认值:
- {}
-
proxyBeanMethods
boolean proxyBeanMethodsSpecify whether@Componentmethods should get proxied in order to enforce bean lifecycle behavior, e.g. to return shared singleton bean instances even in case of direct@Componentmethod 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@Componentmethods, e.g. from another configuration class. If this is not needed since each of this particular configuration's@Componentmethods 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
@Componentmethods individually like when declared on non-@Configurationclasses, a.k.a. "@Component Lite Mode" (see@Component's javadoc). It is therefore behaviorally equivalent to removing the@Configurationstereotype.- 从以下版本开始:
- 4.0
- 默认值:
- true
-