@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
  1. 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
  2. The configuration class must not be final.
  3. Configuration classes must be non-local (that is, cannot be declared in methods).
  4. Any nested configuration classes must be declared static.
  5. The @bean method does not create additional configuration classes (any such instance is treated as a regular Bean, and configuration annotations are not detected).