Springboot: common annotations of springboot

1. @Value

We know that the value in the configuration file can be:

  • Literal
  • Get values from environment variables through ${key}
  • Get the value from the global configuration file through ${key}
  • #{SpEL}

For example:

@Component   
public class Person {   

@Value("i am name")   
private String name;   

}

2. @ConfigurationProperties

If we need to get N configuration items, we need to get them one by one through @Value, which is a little low. We can use @ConfigurationProperties.

All properties of the class marked with @ConfigurationProperties are bound to the relevant configuration items in the configuration file. (get the configuration value from the global configuration file by default). After binding, we can access the attribute value in the global configuration file through this class.

For example, yaml configuration:

person.name=kundy   
person.age=13   
person.sex=male

For example, configuration class:

@Component   
@ConfigurationProperties(prefix = "person")   
public class Person {   

private String name;   
private Integer age;   
private String sex;   
}

3. @Import

@The Import annotation supports importing ordinary java classes and declaring them as a bean. It is mainly used to merge multiple decentralized java config configuration classes into a larger Config class.

@Before 4.2, the Import annotation only supported importing configuration classes.
After 4.2, the @Import annotation supports importing ordinary java classes and declaring them as bean s.

@Three ways to use Import

  • Import ordinary Java classes directly.
  • Use with custom ImportSelector.
  • Used with ImportBeanDefinitionRegistrar.

3.1 import ordinary Java classes directly

1. Create a normal Java class.

public class Circle {   
  public void sayHi() {   
    System.out.println("Circle sayHi()");   
  }    
}

2. Create a configuration class without explicitly declaring any beans, and then import the Circle just created.

@Import({Circle.class})   
@Configuration   
public class MainConfig {   
}

3. Create a test class.

public static void main(String[] args) {   
  ApplicationContext context = new  AnnotationConfigApplicationContext(MainConfig.class);   
  Circle circle = context.getBean(Circle.class);   
  circle.sayHi();   
}

4. Operation results:

Circle sayHi()

We can see that we successfully obtained the Circle object from the IOC container, which proves that the Circle class we imported in the configuration class is indeed declared as a Bean.

3.2 use with customized ImportSelector

ImportSelector is an interface with only one selectImports method, which is used to return an array of full class names. So with this feature, we can dynamically import N beans into the container.

1. Create a common Java class Triangle.

public class Triangle {   

  public void sayHi(){   
    System.out.println("Triangle sayHi()");   
  }   

}

2. Create an ImportSelector implementation class, and selectImports returns the full class name of Triangle.

public class MyImportSelector implements ImportSelector {   
  @Override   
  public String[] selectImports(AnnotationMetadata annotationMetadata) {
    return new String[]{"annotation.importannotation.waytwo.Triangle"};   
  }
}

3. Create a configuration class and import MyImportSelector on the original basis.

@Import({Circle.class,MyImportSelector.class})   
@Configuration   
public class MainConfigTwo {   

}

4. Create a test class

public static void main(String[] args) {   
  ApplicationContext context = new AnnotationConfigApplicationContext(MainConfigTwo.class);   
  Circle circle = context.getBean(Circle.class);   
  Triangle triangle = context.getBean(Triangle.class);   
  circle.sayHi();   
  triangle.sayHi();   

}

5. Operation results:

Circle sayHi() Triangle sayHi()

You can see that the Triangle object has also been successfully instantiated by the IOC container.

3. Use with ImportBeanDefinitionRegistrar

ImportBeanDefinitionRegistrar is also an interface, which can manually register beans into the container, so that we can personalize the class. (it needs to be used with @Import and @Configuration.)

1. Create a normal Java class Rectangle.

public class Rectangle {   

public void sayHi() {   
System.out.println("Rectangle sayHi()");   
}   

}

2. Create an ImportBeanDefinitionRegistrar implementation class, and the implementation method directly manually registers a Bean named rectangle into the IOC container.

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {   

    @Override   
  public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {   

  RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Rectangle.class);   
  // Register a bean named rectangle   
  beanDefinitionRegistry.registerBeanDefinition("rectangle", rootBeanDefinition);   
    }   

}

3. Create a configuration class and import the MyImportBeanDefinitionRegistrar class.

@Import({Circle.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})   
@Configuration   
public class MainConfigThree {   

}

4. Create a test class.

public static void main(String[] args) {   

  ApplicationContext context = new AnnotationConfigApplicationContext(MainConfigThree.class);   
  Circle circle = context.getBean(Circle.class);   
  Triangle triangle = context.getBean(Triangle.class);   
  Rectangle rectangle = context.getBean(Rectangle.class);   
  circle.sayHi();   
  triangle.sayHi();   
  rectangle.sayHi();   

}

5. Operation results

Circle sayHi() Triangle sayHi() Rectangle sayHi()

Yes, the Rectangle object has also been registered.

4. @Conditional

@Conditional annotations enable some configurations only when certain conditions are met.

1. Create a common Java class ConditionBean, which is mainly used to verify whether the Bean is successfully loaded.

public class ConditionBean {   

public void sayHi() {   
System.out.println("ConditionBean sayHi()");   
}   

}

2. Create a condition implementation class. The @condition annotation has only one parameter of condition type. Condition is an interface, which has only one matches() method that returns a Boolean value. If this method returns true, the condition is established and the configuration class takes effect. Otherwise, it will not take effect. In this example, we directly return true.

public class MyCondition implements Condition {   

  @Override   
  public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {   
  return true;   
  }   

}

3. Create a configuration class. You can see that the @Condition of the configuration is passed into the Condition implementation class we just created for Condition judgment.

@Configuration   
@Conditional(MyCondition.class)   
public class ConditionConfig {   

  @Bean   
  public ConditionBean conditionBean(){   
  return new ConditionBean();   
  }   

}

4. Write test methods.

public static void main(String[] args) {   

  ApplicationContext context = new AnnotationConfigApplicationContext(ConditionConfig.class);   
  ConditionBean conditionBean = context.getBean(ConditionBean.class);   
  conditionBean.sayHi();   

}

5. Result analysis because
The conditions' matches method directly returns true, and the configuration class will take effect. We can change matches to return false, and the configuration class will not take effect.

In addition to custom conditions, Spring also extends some common conditions for us. Common notes,

Tags: Spring Boot

Posted by ManOnScooter on Sat, 30 Jul 2022 02:01:18 +0930