Author’s other platforms:

| CSDN:blog.csdn.net/qq_41153943

| the nuggets: juejin. Cn/user / 651387…

| zhihu: www.zhihu.com/people/1024…

| GitHub:github.com/JiangXia-10…

This article is about 1704 words long and 10 minutes is recommended

During Spring annotation development, if multiple instances of a bean are generated, they will all be injected into the IOC container during component registration, such as:

Entity class code:

package com.xinyi.bean;
public class Person {
  private String name;
  private Integer age;
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public Integer getAge() {
    return age;
  }
  public void setAge(Integer age) {
    this.age = age;
  }
  @Override
  public String toString() {
    return "Person [name=" + name + ", age=" + age + "]";
  }
  public Person(String name, Integer age) {
    super();
    this.name = name;
    this.age = age;
  }
  public Person() {
  }
}
Copy the code

Configuration class code:

package com.xinyi.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.xinyi.bean.Person; @configuration public class MyConfig1 {@bean ("Lin Sin") public Person() {return new Person(" Lin Sin",18); } @bean ("Yasuo") public Person person1() {return new Person(" Yasuo",23); } @bean ("Zed") public Person person2() {return new Person(" Zed",32); }}Copy the code

Test class code:

package com.xinyi.test; import org.junit.Test; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import com.xinyi.bean.Person; import com.xinyi.config.MyConfig1; public class IOCTest { @Test public void test3() { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig1.class); String[] names = applicationContext.getBeanNamesForType(Person.class); for(String name:names) { System.out.println(name); } Map<String, Person> persons = applicationContext.getBeansOfType(Person.class); System.out.println(persons); }}Copy the code

Output result:

All three bean instances are injected into the IOC container, but not all bean instances are required during development. Conditional annotations can inject different bean instances according to different requirements. @Conditional is a new annotation provided by Spring4. The purpose of this annotation is to register the bean to the container according to certain conditions. The source of the @Conditional annotation is as follows:

@target ({ElementType.TYPE, {ElementType. ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Conditional { /** * All {@link Condition Conditions} that must {@linkplain Condition#matches match} * in order for the component to be registered. */ Class<? extends Condition>[] value(); }Copy the code

@Conditional annotations can be used on either classes or methods. Conditional annotations accept an array of conditions in their arguments, implementing the Matches method of the Condition interface, according to the source of the Conditional annotation.

@FunctionalInterface
public interface Condition {


  /**
   * Determine if the condition matches.
   * @param context the condition context
   * @param metadata metadata of the {@link org.springframework.core.type.AnnotationMetadata class}
   * or {@link org.springframework.core.type.MethodMetadata method} being checked
   * @return {@code true} if the condition matches and the component can be registered,
   * or {@code false} to veto the annotated component's registration
   */
  boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);


}
Copy the code

Through access to a computer system environment into different bean instance, Condition1 to judge the local system for Windows, Condition2 determine local system if Linux system:

package com.xinyi.condition; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; import org.springframework.core.type.AnnotatedTypeMetadata; Public class Condition1 Condition{/** * ConditionContext: /** * ConditionContext; To determine the context in which the condition can be used, here is the role * AnnotatedTypeMetadata: The current marking the Condition of annotation annotation information * / public Boolean matches (ConditionContext context, AnnotatedTypeMetadata metadata) {// Determine whether the role is wild //1. ConfigurableBeanFactory ConfigurableBeanFactory = Context.getBeanFactory (); ClassLoader = context.getClassLoader(); Environment = context.getenvironment (); BeanDefinitionRegistry = context.getregistry (); BeanDefinitionRegistry = context.getregistry (); String property = environment.getProperty("os.name"); if(property.contains("Windows")) { return true; } return false; }}Copy the code
package com.xinyi.condition; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.env.Environment; import org.springframework.core.type.AnnotatedTypeMetadata; Condition {public Boolean matches(ConditionContext); AnnotatedTypeMetadata metadata) { Environment environment = context.getEnvironment(); String property = environment.getProperty("os.name"); if(property.contains("linux")) { return true; } return false; }}Copy the code

To person and person1 use @ Conditional notes, and assignment Conditional1 and Conditional2 respectively, due to the local system is window10, So Lin Sin and Zed unconditioned Conditional1 were pumped into the container.

package com.xinyi.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Scope; import com.xinyi.bean.Person; import com.xinyi.condition.Condition1; import com.xinyi.condition.Condition2; @configuration public class MyConfig1 {// @scope ("prototype") // default single instance @bean ("Lin Sin") @lazy Conditional(condition1.class) public Person () {// condition.out.println (" condition1.class "); Return new Person(" Li Qing ",18); } @conditional (condition2.class) @bean ("Yasuo") public Person person1() {return new Person(" condition2.class ",23); } @bean ("Zed") public Person person2() {return new Person(" Zed",32); }}Copy the code

Then right-click Run as –> Run Configurations —–> Select Arguments Type -dos. name= Linux in VM Arguments to set the runtime system environment to Linux. Conditional2 Yasuo and Zed, conditional-free, were pumped into the container.

Conditional(condition1.class) can be applied not only to methods but also to classes. Conditionconditionconditioncondition1.class indicates that all bean registrations in the class are valid if conditions are met, but not otherwise.

package com.xinyi.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Scope; import com.xinyi.bean.Person; import com.xinyi.condition.Condition1; import com.xinyi.condition.Condition2; Conditionconditionconditionconditionconditioncondition1.class public class MyConfig1 {// @scope ("prototype") @lazy @conditional (condition1.class) public Person Person () {// system.out.println ("IOC "); Return new Person(" Li Qing ",18); } // @conditional (condition2.class) @bean ("Yasuo") public Person person1() {return new Person(" condition2.class ",23); } @bean ("Zed") public Person person2() {return new Person(" Zed",32); }}Copy the code

If all beans are injected into the IOC container and the computer environment parameters are modified and the @Conditional annotation is changed to Linux, none of the components are injected into the container.

This is the injection of components based on conditions using the @Conditional annotation.

Finally, welcome to pay attention to the public number: 1024 notes, free access to massive learning resources (including video, source code, documents)!

Related recommendations:

  • Spring annotation (2) : @ComponentScan Automatically scans components
  • Spring is worth your collection!!
  • Spring annotation (7) : Assign attributes to beans using @value
  • SpringBoot develops Restful interfaces to implement CRUD functions
  • Introduction to distributed cache middleware Redis