【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)用上面的测试类再次验证,同样可以

原文地址:https://www.cnblogs.com/756623607-zhang/p/12037291.html

时间: 2024-08-05 10:03:07

【Spring Boot】Spring Boot之使用ImportBeanDefinitionRegistrar类实现动态注册Bean的相关文章

spring boot 动态注入bean

方法一 SpringContextUtil public class SpringContextUtil { private static ApplicationContext applicationContext; //获取上下文 public static ApplicationContext getApplicationContext() { return applicationContext; } //设置上下文 public static void setApplicationCont

spring boot 如何将没有注解的类@Autowired

等于将类交给spring管理,也就是IOC. 注解@Autowired是自动装配,也就是spring帮你创建对象,当然前提是这个@Autowired的类已经配置成Bean了,spring配置bean文件我们常用的方法是编写配置文件.而spring boot则不需要这么麻烦,它提供了两个注解可以实现这个功能. [email protected] [email protected] 虽然@Configuration注解本质上还是 @Component,但是,两者是有区别的.这里简单的提一下,需要深入

Spring boot +Spring Security + Thymeleaf 认证失败返回错误信息

spring boot以其众多友谊的特性,如零配置.微服务等,吸引了很多的粉丝.而其与Spring Security安全框架的无缝结合,使其具备的安全的特性.在此基础上使用Thymeleaf模板引擎进行渲染,静动态结合,让页面开发更加简单.直观. 通过表单提交登录的用户名和密码是登录接口比较常见的一种设计.在初学的过程中,我也不例外的采用个这种方式.表单设计见下图. 登录成功,完成正常的主页面跳转,这个不存在问题.存在问题的是,登录失败了该咋办呢?我就在考虑,由于thymeleaf的局部刷新操作

spring/spring boot/spring cloud开发总结

背景        针对RPC远程调用,都在使用dubbo.dubbox等,我们也是如此.由于社区暂停维护.应对未来发展,我们准备尝试新技术(或许这时候也不算什么新技术了吧),选择使用了spring cloud架构.在此期间使用spring boot项目尝试开发,结果良好.所以想重构原spring项目至spring cloud一步一步进行,因此开发中会出现各种问题.  问题 问题总是伴随着开发一步一步显露出来,遇到问题总要去解决: spring cloud相关问题: 1.跨系统调用,传参对象接收

Spring Boot/Spring Cloud、ESB、Dubbo

如何使用Spring Boot/Spring Cloud 实现微服务应用spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全局锁.决策竞选.分布式会话和集群状态管理等操作提供了一种简单的开发方式. Spring Cloud与Dubbo对比提到Dubbo,我想顺便提下ESB,目前央视新华社也在用ESB来做任务编排,这里先比较下Dubbo和ESB: ESB(企业数据总线),一般采用集中式

【spring】Spring Boot:定制自己的starter

概念 在学习Spring Boot的过程中,接触最多的就是starter.可以认为starter是一种服务--使得使用某个功能的开发者不需要关注各种依赖库的处理,不需要具体的配置信息,由Spring Boot自动通过classpath路径下的类发现需要的Bean,并织入bean 步骤 引入spring boot 的配置 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>s

Spring Boot整合Spring MVC、Spring、Spring Data JPA(Hibernate)

一句话总结:Spring Boot不是新的功能框架,而是为了简化如SSH.SSM等等多个框架的搭建.整合及配置.使用Spring Boot 10分钟搭建起Spring MVC.Spring.Spring Data JPA(Hibernate)基础后台架构.基本零配置,全注解. 步骤一: 使用Spring Boot提供的网站生成maven项目及基础依赖.打开https://start.spring.io/网站,右侧输入想要的特性依赖.输入Web提供整合Spring MVC,输入JPA提供整合Spr

Spring和Spring Boot的属性

1.概述 本教程将展示如何在Spring中设置和使用Properties - 通过Java配置和@PropertySource或通过XML和<property-placeholder>,以及属性如何在Spring Boot中工作. 2.通过Java注解注册属性文件 Spring 3.1还引入了新的@PropertySource注解,作为向环境添加属性源的便捷机制.此注解将与基于Java的配置和@Configuration批注结合使用:(注意,只能引入properties,不能引入yml) @C

255.Spring Boot+Spring Security:使用md5加密

说明 (1)JDK版本:1.8 (2)Spring Boot 2.0.6 (3)Spring Security 5.0.9 (4)Spring Data JPA 2.0.11.RELEASE (5)hibernate5.2.17.Final (6)MySQLDriver 5.1.47 (7)MySQL 8.0.12 需求缘起 很多时候,我们自己已经有现成的一套系统在运行了,这时候要接入spring security的话,那么难免会碰到一个问题:就是自己设计的密码加密方式和spring secur