Punto de extensión del resorte 3: @Import annotation

El papel de la anotación @Import

Hablando de la anotación @Import, lo que hay que decir es que
en los métodos de implementación correspondientes a la interfaz ImportSelector de las siguientes dos clases , se debe devolver una matriz. En la matriz, el nombre completo de la clase correspondiente a la clase que se inyectará en el contenedor de primavera es
la implementación de la interfaz ImportBeanDefinitionRegistrar. En el método, se proporcionará un objeto BeanDefinitionRegistry, y podemos inyectar un objeto beanDefinition en el beanDefinitionMap a través del objeto en el método.
Esta es la función de estas dos clases.

En el código fuente de primavera, la anotación @Import es la más utilizada, lo cual no es una exageración. De hecho, en la mayoría de los marcos, verá que cada marco personaliza muchas anotaciones. La mayoría de estas anotaciones se utilizan La anotación @Import y, a través de la anotación @Import, la inyección es generalmente la clase
de implementación de ImportSelector o ImportBeanDefinitionRegistrar. En cuanto al principio de estos dos puntos de extensión, el código fuente de primavera
en el blog anterior : @Import annotation , hay un registro Sí , así que no daré demasiada explicación, resumámoslo a grandes rasgos.

1. En el código fuente de Spring, para convertir un objeto de clase en un objeto bean que pueda ser recibido por un contenedor Spring, primero convierta el objeto de clase en un objeto beanDefinition. En el proceso de conversión, el escaneo y la conversión generalmente se completan a través del @ComponentScan anotación de
2, pero un punto a considerar: puede haber ImportSelector, inyectamos la clase de implementación del bean o ImportBeanDefinitionRegistrar, mientras que ImportSelector la clase inyectada, es posible que haya una clase de implementación ImportSelector o ImportBeanDefinitionRegistrar, por lo que, en el código fuente, un recursivo Se hará un juicio, hasta que el bean actual sea un bean ordinario, y luego todos los beans se almacenen en una colección
3. Cabe señalar que en este momento, las clases de implementación ImportSelector e ImportBeanDefinitionRegistrar introducidas por @Import, el bean devuelto es sigue siendo un objeto de clase ordinario y no se ha convertido en beanDefinition. Una vez completado el análisis, Spring procesará estas dos clases de implementación de una manera unificada.

4. El llamado procesamiento unificado se basa en si la inyección importBeanDefinitionRegistrar o ImportSelector o @Bean actual se procesa, se convierte a beanDefinition y luego se almacena en beanDefinitionMap

solicitud

A continuación, hablo principalmente de aplicaciones. De hecho, para las anotaciones de @Import,
1. Podemos introducir directamente un bean común a través de @Import
2. También puede introducir una clase de implementación de ImportSelector
3. También puede introducir una clase de implementación de ImportBeanDefinitionRegistrar

ImportBeanDefinitionRegistrar

@Configuration
@ComponentScan("com.spring.study.importbeandefinitionregistrar")
@Import({
    
    MyImportBeanDefinitionRegistrar.class,ImportTestBean.class})
public class ImportConfig {
    
    
}
public class ImportTestBean {
    
    
}
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    
    

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    
    
        System.out.println("自己手动注入一个bean");
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(OrderBean.class);
        registry.registerBeanDefinition("orderBean", beanDefinitionBuilder.getBeanDefinition());
    }
}
public class OrderBean {
    
    
}
public class TestImportBeanDefinitionRegistrar {
    
    
    public static void main(String[] args) {
    
    
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(ImportConfig.class);
        System.out.println(ac.getBean(OrderBean.class));
        System.out.println(ac.getBean(ImportTestBean.class));
    }
}

El resultado final de la impresión

自己手动注入一个bean
18:49:04.903 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerProcessor'
18:49:04.906 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerFactory'
18:49:04.907 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
18:49:04.909 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
18:49:04.927 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'importConfig'
18:49:04.936 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'com.spring.study.importbeandefinitionregistrar.ImportTestBean'
18:49:04.936 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'orderBean'
com.spring.study.importbeandefinitionregistrar.OrderBean@43301423
com.spring.study.importbeandefinitionregistrar.ImportTestBean@2f112965

La anotación @Import aquí inyecta dos clases, una es un bean normal y la otra es una clase de implementación de importBeanDefinitionRegistrar.
Por lo tanto, el papel de la interfaz ImportBeanDefinitionRegistrar es dar el BeanDefinitionRegistry al programador, y el programador mismo decide la lógica de negocios para acabar.

ImportSelector

public class MyImportSelector implements ImportSelector {
    
    

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
    
    
        return new String[]{
    
    "com.spring.study.importselector.OperChannelEntity","com.spring.study.importselector.UserBean"};
    }
}

ImportSelector no publicará demasiado código, siempre que este bean se importe a través de la anotación @Import, Spring nos ayudará a inyectar las dos clases de OperChannelEntiry y UserBean

La inyección automática de springboot usa este punto para implementar ImportSelector, y luego obtener el nombre de clase completo del bean que se inyectará automáticamente y luego colocarlo en la matriz devuelta.

Supongo que te gusta

Origin blog.csdn.net/CPLASF_/article/details/115207928
Recomendado
Clasificación