In this paper, the content

  1. @ResourceImplementing dependency injection
  2. @ValueUse in detail
  3. @PostConstruct @PreDestroyThe use of

@ResourceImplementing dependency injection

The previous section covered the detailed use of @AutoWired injection dependencies, so those interested should check out the previous article. Spring also supports injection by using jSR-250@Resource annotations on Setter methods of fields or beans.

@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
public @interface Resource {
	// Specify a name
    String name(a) default "";
}
Copy the code

The basic use

Dependent component definition

@Component
public class RepositoryA implements RepositoryBase {}@Component
public class RepositoryB implements RepositoryBase {}Copy the code

Inject dependencies using @Resource

@Component
public class Service1 {
    / / field
    @Resource
    private RepositoryA repositoryA;

    private RepositoryB repositoryB;

    / / Setter methods
    @Resource
    public void setRepositoryB(RepositoryB repositoryB) {
        this.repositoryB = repositoryB;
    }
	// ...
  
}
Copy the code

Run the test

@org.junit.Test
public void test(a) {
    AnnotationConfigApplicationContext context =
            new AnnotationConfigApplicationContext(AppConfig.class);
    Service1 service1 = context.getBean(Service1.class);
    System.out.println(service1);
    context.close();
}
/ / the result
Service1{repositoryA=com.crab.spring.ioc.demo09.RepositoryA@1622f1b, repositoryB=com.crab.spring.ioc.demo09.RepositoryB@72a7c7e0}
Copy the code

@Resourceand@AutowiredThe difference between

  1. Different range of use:@ResourceThe use scope is class field andSetterMethod,@AutowiredWider scope: class fields,SetterMethod, constructor, method parameters.
  2. When dependency is absent,@ResourceInjection will report an error,@Autowired(required=false)Errors can be avoided.
  3. @ResourceThere are properties to specify the name of the dependent bean,@Autowiredand@QulifierYou can do the same thing.

@ValueUse in detail

@Value is typically used to inject externalized attributes. Annotations used at the field or method constructor parameter level to indicate the default value expression for the annotation element.

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Value {

	#{systemproperties.myprop}
	// or property placeholders such as ${my.app.myProp}
	String value(a);
}
Copy the code

Case 1

Use @value to inject configuration property values

@Component
public class MovieRecommender {
   private final  String catalog;

   public MovieRecommender(@Value("${catalog.name}") String catalog) {
      this.catalog = catalog;
   }

   // ...
}
Copy the code

External demo10 / application configuration file. The properties

catalog.name=MovieCatalog
Copy the code

File resources are configured in the container via @propertysource

@Configuration
@ComponentScan(basePackages = "com.crab.spring.ioc.demo10")
@PropertySource("classpath:demo10/application.properties")
public class AppConfig {}Copy the code

Run the test

@org.junit.Test
public void test(a) {
    AnnotationConfigApplicationContext context =
            new AnnotationConfigApplicationContext(AppConfig.class);
    MovieRecommender recommender = context.getBean(MovieRecommender.class);
    System.out.println(recommender);
    context.close();
}
/ / the result
MovieRecommender{catalog='MovieCatalog'}
Copy the code

As a result, the property values in the external configuration file were successfully injected.

Case 2: Attribute values could not be resolved

Spring provides a loose embedded value parser by default. It will attempt to resolve the attribute value, and if it cannot, the attribute name (for example, ${catalog.name}) will be injected as the value.

Modify the content of the configuration file as follows

xxx.catalog.name=MovieCatalog	
Copy the code

Running the same test as in the previous case, you can see that the attribute name is injected when the attribute value cannot be resolved.

MovieRecommender{catalog='${catalog.name}'}	
Copy the code

If there is no value must be strictly controlled, can declare a PropertySourcesPlaceholderConfigurer and injected into the Spring

@Configuration
@ComponentScan(basePackages = "com.crab.spring.ioc.demo10")
@PropertySource("classpath:demo10/application.properties")
public class AppConfig {
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer(a) {
        return newPropertySourcesPlaceholderConfigurer(); }}Copy the code

Run the same test program and throw an exception in strict mode

java.lang.IllegalArgumentException: Could not resolve placeholder 'catalog.name' in value "${catalog.name}"
Copy the code

Extension: Spring Boot default configuration a PropertySourcesPlaceholderConfigurer bean, it will be from the application. The properties and application. The yml file access attributes.

Case 3: Provide default values

Default values can be provided as property values injected when unable to resolve property values.

@Component
public class MovieRecommender {
   private final  String catalog;

   public MovieRecommender(@Value("${catalog.name:defaultCatalog}") String catalog) {
      this.catalog = catalog; }}Copy the code

The configuration file is as follows

xxx.catalog.name=MovieCatalog
Copy the code

Run the same test program and inject the default values

MovieRecommender{catalog='defaultCatalog'}
Copy the code

Case 4: Support for SpEL expressions

The SpEL expression is not expanded here.

@PostConstruct @PreDestroyThe use of

Spring supports lifecycle callback interface annotations, @postConstruct @Predestroy provided by JSR 250.

The @postConstruct annotated method calls back at the bean initialization stage of the container.

The @postConstruct annotation method calls back during the container destruction bean phase.

Let’s go straight to the case

@Component
public class FoodRecommender {

   @PostConstruct
   public void onInit(a) {
      System.out.println("FoodRecommender onInit");
   }
   @PreDestroy
   public void onDestroy(a) {
      System.out.println("FoodRecommender onDestroy"); }}Copy the code

The configuration of the annotations is equivalent to the following XML configuration file

<bean class="com.crab.spring.ioc.demo10.FoodRecommender" id="foodRecommender"
      init-method="onInit"
      destroy-method="onInit"></bean>
Copy the code

Run the test program and observe the results

@org.junit.Test
public void test1(a) {
    System.out.println(Start initializing the container);
    AnnotationConfigApplicationContext context =
            new AnnotationConfigApplicationContext(AppConfig.class);
    FoodRecommender bean = context.getBean(FoodRecommender.class);
    System.out.println("Use in containers.");
    System.out.println("Destroy containers.");
    context.close();
}
/ / the resultStart initializing the container FoodRecommender onInit using the container to destroy the container FoodRecommender onDestroyCopy the code

conclusion

This article introduces dependency injection for @Resource, detailed use of @Value, and use of @postConstruct @Predestroy.

This source code address: github.com/kongxubihai…

Knowledge sharing, reproduced please indicate the source. Learning has no priority, the first!