This is the 16th day of my participation in the August Text Challenge.More challenges in August

@import is one of the ways Spring injects beans.

Why do we have this?

Let’s look at some other ways:

  • Needless to say, @Component and its corresponding derivative annotations can only be found in the current package, or in the path of @ComponentScan. This is convenient for your own project, but not when you need to combine it with a third project.
  • The @bean injection method is usually used to import third-party components: other components have object class information and we inject it. This approach involves writing methods in @Configuration, which is inconvenient if the business logic is complex or there is too much to inject.

We need to have some other injection requirements:

  1. Dynamically injected beans: Bean injection is not written in logic, but based on certain user usage conditions. This is what the framework needs, and we should decide what beans we inject into the container, depending on how the user configits it.
  2. Load a Configuration file before loading another Configuration file: there are other ways to do this, but it is better to use @import for the @Configuration class.
  3. Batch injection of beans: If a framework wants to inject many beans after the user configures an item, Import can write code to logically batch inject beans.
  4. Continuous replenishment…

@import is usually used when Spring is integrated with other frameworks. When we use @Component and its components, these components can be scanned by our own project, but when we need to load components from other frameworks that are not in our project package, we can use @import to load them. In addition, the default @import injection is loaded before the current configuration class (except for the DeferredImportSelector implementation class).

usage

@import can be used in three ways

Importing ordinary classes

You can import a normal class or an @Configuration annotated class, in which case the Configuration class will be loaded first.

@Import(value = {Bean.class, Configuration.class})
Copy the code

Import the ImportSelector interface implementation class

The main function is to collect configuration classes that need to be imported, injecting the object with the ID returned by the selectImports method into the Spring container.

This is used by SpringBoot automation and the @enablexxx annotation, which determines which bean to inject into the container based on the parameter values obtained from the annotation.

@Import(value = {CustomImportSelector.class}) public class CustomImportSelector implements ImportSelector { @Override Public String[] selectImports(AnnotationMetadata importingClassMetadata) {// Returns the fully qualified class name of the class, which generates the bean regardless of whether the class is Spring annotated. return new String[]{"com.xx.Bean"}; }}Copy the code

Common methods:

  1. Implement the class directly on the configuration class using @import ImportSelector
  2. Implement the class via the EnableXXX annotation @import ImportSelector on the Enable annotation, and then use the parameters in the Eanble annotation to determine which configuration Bean to load into the Spring container.

When will it be used?

  • Scenarios where similar functions like @enablexxx need to be customized
  • Scenarios that require batch injection beans

Import ImportBeanDefinitionRegistrar interface implementation class

ImportBeanDefinitionRegistrar is an interface, this class is just registering beans have more freedom, let myself to create BeanDefinition and register to the container. This is suitable for more complex framework integration where we can be more flexible in customizing the bean elements we need to inject into the container.

@Import(value = {CustomBeanDefinitionRegister.class})
​
public class CustomBeanDefinitionRegister implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Bean.class);
        registry.registerBeanDefinition("bean", rootBeanDefinition);
    }
}
Copy the code