【Spring Boot】Spring BootのImportBeanDefinitionRegistar類を使って動的登録Beanを実現します.

9018 ワード

一、ImportBeanDefinitionRegistrar類の紹介
ImportBeanDefinitionRegistar類は他の@Configration類を通じて@Importの方式でロードされています.通常は起動類または配置類です.その後、このインターフェース方法を呼び出して、登録するクラスをbeanに登録します.このインターフェースを実現するクラスによって、ベスンを登録する能力がある.Awareインターフェースを残したEvironment Aware BenFactory Aware BeanClass Loader Aware Resource Loader Awareを実現できます.
二、登録指定タイプを実現するBean
1)登録するために必要なserviceクラスを定義する.
/**
 * @author zhangboqing
 * @date 2019/12/13
 */
@Slf4j
public class HelloService {
    public void sayHello() {
      log.info("Hello!!!");
    }
}
2)ハローImportBenDefinitionRegistar類を定義し、ImportBenDefinitionRegistarインターフェースを実現する.
/**
 * @author zhangboqing
 * @date 2019/12/13
 */
public class HelloImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        //     
        Map annotationAttributes = importingClassMetadata.getAnnotationAttributes(ComponentScan.class.getName());
        String[] basePackages = (String[]) annotationAttributes.get("basePackages");

        //    
        ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry, false);
        //    
        TypeFilter helloServiceFilter = new AssignableTypeFilter(HelloService.class);
        scanner.addIncludeFilter(helloServiceFilter);
        scanner.scan(basePackages);
    }
}
3)ハローConfigrationの配置類を定義し、ImportBeanDefinitionRegistrarを導入する.
/**
 * @author zhangboqing
 * @date 2019/12/13
 */
@Configuration
@ComponentScan("com.zbq.springbootdemo.speciality.dynamicRegisterBean.ImportBeanDefinitionRegistrar")
@Import(HelloImportBeanDefinitionRegistrar.class)
public class HelloConfiguration {
}
4)試験類を定義し、ハローサービス類の登録が成功したかどうかを検証することができる.
/**
 * @author zhangboqing
 * @date 2019/12/13
 */
@SpringBootTest(classes = {HelloConfiguration.class})
//      
//@ContextConfiguration(classes = {HelloConfiguration.class})
public class HelloImportBeanDefinitionRegistrarTest {

    @Autowired
    private HelloService helloService;

    @Test
    public void testHelloService() {
        helloService.sayHello();
    }
}
三、登録指定の注釈を実現するBean
1)カスタムコメントHello Annotation
/**
 * @author zhangboqing
 * @date 2019/12/13
 */
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface HelloAnnotation {
}
2)HelloService類に注解を加える
/**
 * @author zhangboqing
 * @date 2019/12/13
 */
@Slf4j
@HelloAnnotation
public class HelloService {
    public void sayHello() {
      log.info("Hello!!!");
    }
}
3)ハローImportBeanDefinitionRegistar類を修正し、タイプフィルタを指定のタイプから指定の注釈に変更します.
/**
 * @author zhangboqing
 * @date 2019/12/13
 */
public class HelloImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        //     
        Map annotationAttributes = importingClassMetadata.getAnnotationAttributes(ComponentScan.class.getName());
        String[] basePackages = (String[]) annotationAttributes.get("basePackages");

        //    
        ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry, false);
        //    
//        TypeFilter helloServiceFilter = new AssignableTypeFilter(HelloService.class);
        //     
        TypeFilter helloServiceFilter = new AnnotationTypeFilter(HelloAnnotation.class);
        scanner.addIncludeFilter(helloServiceFilter);
        scanner.scan(basePackages);
    }
}
4)上の試験類で再度検証してもいいです.