@Configuration Explanation
Configuration Code introduction
Configuration annotation classes indicate that their primary purpose is to serve as a source for bean definitions; The @Configuration class allows dependencies between beans to be defined by calling other @bean methods in the same class
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
String value(a) default "";
}
Copy the code
A class declares one or more @bean methods and can be processed by the Spring container to generate Bean definitions and service requests for these beans at run time, for example:
public class AppConfig {
@Bean
public MyBean myBean(a) {
// instantiate, configure and return bean ...}}Copy the code
@ Configuration interpretation
@Configuration This class is used AnnotationConfigApplicationContext or which has the function of Web org. Springframework. Web. Context. Support. AnnotationConfigWebApplicationContext AnnotationConfigWebApplicationContext guided, as follows
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class);
ctx.refresh();
MyBean myBean = ctx.getBean(MyBean.class);
// use myBean ...
Copy the code
Directly on the AnnotationConfigApplicationContext registered @ the alternative method of the Configuration class, can the Spring XML file will be @ the Configuration class declaration for the common definition:
<beans>
<context:annotation-config/>
<bean class="com.acme.AppConfig"/>
</beans>}
Copy the code
In the example above, the config / > < context: an annotation, enable ConfigurationClassPostProcessor associated with annotations and other post processor, to deal with @ Configuration.
@Configuration is meta-annotated with @Component, so the @Configuration class can be scanned by components; Use Spring XML’s <context: component-scan />, so you can use @autowired or javax.inject.Inject @inject just like @Component. If there is a single constructor, the autowage semantics are transparently applied
@Configuration
public class AppConfig {
private final SomeBean someBean;
public AppConfig(SomeBean someBean) {
this.someBean = someBean;
}
// @Bean definition using "SomeBean"
}
Copy the code
@ Configuration techniques
- Can pass to Spring’s org. Springframework. Core. The env. The Environment into @ the Configuration class is required in the external Environment value; For example, use the @autowired annotation:
@Configuration
public class AppConfig {
@Autowired Environment env;
@Bean
public MyBean myBean(a) {
MyBean myBean = new MyBean();
myBean.setName(env.getProperty("bean.name"));
returnmyBean; }}Copy the code
- Environment parse attributes reside in one or more “attribute source” object, @ Configuration can use org. Springframework. Core. The env. PropertySources @ PropertySources comments:
@Configuration
@PropertySource("classpath:/com/acme/app.properties")
public class AppConfig {
@Inject Environment env;
@Bean
public MyBean myBean(a) {
return new MyBean(env.getProperty("bean.name")); }}Copy the code
- Externalized values can be wired into the @Configuration class using @Value
@Configuration
@PropertySource("classpath:/com/acme/app.properties")
public class AppConfig {
@Value("${bean.name}") String beanName;
@Bean
public MyBean myBean(a) {
return newMyBean(beanName); }}Copy the code
When using the Spring org. Springframework. Context. Support. PropertySourcesPlaceholderConfigurer PropertySourcesPlaceholderConfigurer, usually use < context: the property placeholder / > XML open it.
- The @Configuration class can be composed with the @import annotation, which works differently than in Spring XML. The @Configuration object is managed as a Spring bean in the container, so the imported Configuration can be injected in the normal way (for example, via constructor injection) :
@Configuration
public class DatabaseConfig {
@Bean
public DataSource dataSource(a) {
// 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(a) {
// reference the dataSource() bean method
return newMyBean(dataConfig.dataSource()); }}Copy the code
So you can boot AppConfig and the imported DatabaseConfig by registering AppConfig only for the Spring context
new AnnotationConfigApplicationContext(AppConfig.class);
Copy the code
The @Configuration class can be marked with the @Profile annotation to indicate that a given Profile should only be processed if one or more profiles are active
@Profile("development")
@Configuration
public class EmbeddedDatabaseConfig {
@Bean
public DataSource dataSource(a) {
// instantiate, configure and return embedded DataSource}}Copy the code
Alternatively, you can declare configuration file conditions at the @Bean method level, for example. For alternative bean variants in the same configuration class:
@Configuration
public class ProfileDatabaseConfig {
@Bean("dataSource")
@Profile("development")
public DataSource embeddedDatabase(a) {... }@Bean("dataSource")
@Profile("production")
public DataSource productionDatabase(a) {... }}Copy the code
As mentioned above, the @Configuratio} class can be declared as a regular Spring definition in an XML file. You can also import the Spring XML Configuration file into the @Configuration class using the @ImportResource annotation. Bean definitions imported from XML can be injected in the usual way (for example, using Inject annotations)
@Configuration
@ImportResource("classpath:/com/acme/database-config.xml")
public class AppConfig {
@Inject DataSource dataSource; // from XML
@Bean
public MyBean myBean(a) {
// inject the XML-defined dataSource bean
return new MyBean(this.dataSource); }}Copy the code
- The @Configuration class can be nested with each other, as follows:
@Configuration
public class AppConfig {
@Inject DataSource dataSource;
@Bean
public MyBean myBean(a) {
return new MyBean(dataSource);
}
@Configuration
static class DatabaseConfig {
@Bean
DataSource dataSource(a) {
return newEmbeddedDatabaseBuilder().build(); }}}Copy the code
When booting like this, only AppConfig needs to be registered for the application context. Since it is nested @Configuration, DatabaseConfig will be automatically registered. Avoid using the @import annotation when the relationship between appConfig.databaseconfig has been implicitly cleared. Note that the nested @Configuration class can be used with the @Profile annotation to provide two options of the same bean for the closed @Configuration. By default, the @bean method is instantiated when the container boots. To avoid this, you can use @Configuration with the @lazy annotation to indicate that by default all @bean methods declared in the class are initialized by default. @lazy can also be used on a separate @bean method.
- The @ContextConfiguration annotation is provided by spring’s TestContext framework in the Spring-test module. As of Spring 3.1, this annotation can accept the @Configuration array-like object:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={AppConfig.class, DatabaseConfig.class})
public class MyTests {
@Autowired MyBean myBean;
@Autowired DataSource dataSource;
@Test
public void test(a) {
// assertions against myBean ...}}Copy the code
Use the @Enable annotation to Enable built-in Spring functionality such as asynchronous method execution, scheduled task execution, annotation-driven transaction management, and Spring functionality of the SpringMVC class can all be enabled and configured through the @Configuration class using their respective “@Enable” annotations. Such as
Org. Springframework. Scheduling. The annotation. EnableAsync, @ EnableAsync org. Springframework. Scheduling. The annotation. EnableScheduling @ EnableScheduling, org.springframework.transaction.annotation.EnableTransactionManagement @EnableTransactionManagement Org. Springframework. Context. The annotation. EnableAspectJAutoProxy @ EnableAspectJAutoProxy, rg.springframework.web.servlet.config.annotation.EnableWebMvc @EnableWebMvc
@ Configuration constraints
- The Configuration class must be provided as a class (that is, not as an instance returned from a factory method) to allow the runtime to be enhanced through the generated subclasses
- The configuration class must not be final.
- Configuration classes must be non-local (that is, cannot be declared in methods).
- Any nested configuration classes must be declared static.
- The @bean method does not create additional configuration classes (any such instance is treated as a regular Bean, and configuration annotations are not detected).