Spring injects components through annotations

Keywords: PHP SpringBoot Druid Spring

Component declaration

Annotations such as @Component, @Configuration, @RestController, @Service, @Repository are declared on the class to indicate that the class needs to be injected into the IoC container.

1, @Configuration and @Bean

@Configuration is often used in conjunction with @Bean to inject third-party components.

Example: Injecting Druid data source

@Configuration
public class DruidConfig {
  @Bean
  @ConfigurationProperties(prefix = "spring.datasource")
  public DataSource druidDataSource() {
    return new DruidDataSource();
  }
}

2,FactoryBean

Inject by implementing the interface FactoryBean

Example: Injecting Dog with FactoryBean

// Implement FactoryBean
public class DogFactoryBean implements FactoryBean<Dog> {

  // object
  @Override
  public Dog getObject() throws Exception {
    return new Dog();
  }

  // type
  @Override
  public Class<?> getObjectType() {
    return Dog.class;
  }

  // Is singleton, true means singleton
  @Override
  public boolean isSingleton() {
    return true;
  }
}
// Inject DogFactoryBean
@Configuration
public class MyConfig {
  @Bean
  DogFactoryBean dog() {
    return new DogFactoryBean();
  }
}

Dog objects in containers can be obtained by name dog; if you want to get a DogFactoryBean object, you can get it by &dog.

3,@Import

Declares on the class that multiple third-party classes can be injected quickly, often in conjunction with ImportSelector, ImportBeanDefinitionRegistrar

Examples: Injecting Dog, Cat classes
Mode 1: Annotation injection

@Import({Dog.class, Cat.class})
public class MyConfig {}

Mode 2: Implement the interface ImportSelector

// ImportSelector implementation
public class MyImport implements ImportSelector {
  @Override
  public String[] selectImports(AnnotationMetadata metadata) {
    return new String[]{"com.xxx.Dog", "com.xxx.Cat"};
  }
}
// Import MyImport
@Import({MyImport.class})
public class MyConfig {}

Mode 3: Implement the interface ImportBeanDefinitionRegistrar

// ImportBeanDefinitionRegistrar Implementation
public class MyImportBean implements ImportBeanDefinitionRegistrar {
  @Override
  public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
    BeanDefinition dogBean = new RootBeanDefinition(Dog.class);
    registry.registerBeanDefinition("dog", dogBean);
    BeanDefinition catBean = new RootBeanDefinition(Cat.class);
    registry.registerBeanDefinition("cat", beanDefinitions);
  }
}
// Import MyImportBean
@Import({MyImportBean.class})
public class MyConfig {}

4,@Conditional

You can customize conditions before injecting components.

Example: Cat is injected when there is a Dog in the container

// Implement Condition
public class MyCondition implements Condition {
  @Override
  public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
    for (String name : Objects.requireNonNull(context.getBeanFactory()).getBeanDefinitionNames()) {
      if ("com.xxx.Dog".equals(name)) {
        return true;
      }
    }
    return false;
  }
}
// Conditional Injection of Cat
@Configuration
public class MyConfig {
    @Conditional(MyCondition.class)
    @Bean
    Cat cat() {
        return new Cat();
    }
}

Springboot provides some @Conditional implementations

@ConditionalOnClass: Effective when this class exists
 @ConditionalOnBean: The Bean is active when it exists
 @ConditionalOnProperty: Effective when configured correctly
 @ConditionalOnResource: Resource Existence Is Active

5. Other Notes

Comments on the order in which configuration takes effect provided by Springboot

@AutoConfigureAfter: Inject after the specified configuration class takes effect
 @AutoConfigureBefore: Inject after the specified configuration class takes effect

Posted by Oxymen on Tue, 30 Jul 2019 10:47:49 -0700