zoukankan      html  css  js  c++  java
  • 【Spring Boot】Spring Boot之使用ImportBeanDefinitionRegistrar类实现动态注册Bean

    一、ImportBeanDefinitionRegistrar类介绍

      ImportBeanDefinitionRegistrar类通过其他@Configuration类通过@Import的方式来加载,通常是启动类或配置类。
      然后会调用该接口方法,将其中要注册的类注册成bean。
      通过实现该接口的类拥有注册bean的能力。
      可以实现遗下Aware接口
        EnvironmentAware
        BeanFactoryAware
        BeanClassLoaderAware
        ResourceLoaderAware

    二、实现注册指定类型的Bean

    1)定义一个需要用来注册的service类

    /**
     * @author zhangboqing
     * @date 2019/12/13
     */
    @Slf4j
    public class HelloService {
        public void sayHello() {
          log.info("Hello!!!");
        }
    }

    2)定义HelloImportBeanDefinitionRegistrar类实现ImportBeanDefinitionRegistrar接口

    /**
     * @author zhangboqing
     * @date 2019/12/13
     */
    public class HelloImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    
        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            // 扫描注解
            Map<String, Object> 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)定义HelloConfiguration配置类,引入ImportBeanDefinitionRegistrar

    /**
     * @author zhangboqing
     * @date 2019/12/13
     */
    @Configuration
    @ComponentScan("com.zbq.springbootdemo.speciality.dynamicRegisterBean.ImportBeanDefinitionRegistrar")
    @Import(HelloImportBeanDefinitionRegistrar.class)
    public class HelloConfiguration {
    }

    4)定义测试类可验证HelloService类是否注册成功

    /**
     * @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)自定义注解HelloAnnotation

    /**
     * @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)修改HelloImportBeanDefinitionRegistrar类,将类型过滤器从指定类型变为指定注解

    /**
     * @author zhangboqing
     * @date 2019/12/13
     */
    public class HelloImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    
        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            // 扫描注解
            Map<String, Object> 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)用上面的测试类再次验证,同样可以

  • 相关阅读:
    670. Maximum Swap
    653. Two Sum IV
    639. Decode Ways II
    636. Exclusive Time of Functions
    621. Task Scheduler
    572. Subtree of Another Tree
    554. Brick Wall
    543. Diameter of Binary Tree
    535. Encode and Decode TinyURL
    博客园自定义背景图片
  • 原文地址:https://www.cnblogs.com/756623607-zhang/p/12037291.html
Copyright © 2011-2022 走看看