Administrator
发布于 2023-09-09 / 104 阅读 / 0 评论 / 0 点赞

ImportBeanDefifinitionRegistrar(自定义自动装配)

自定义自动注入案例解析

@FeignClient解析

这个注解开启了FeignClient的解析过程

@EnableFeignClients(basePackages = "org.example.client")

这个注解的声明如下,它用到了一个@Import注解,我们知道Import是用来导入一个配置类的,接下来

去看一下FeignClientsRegistrar的定义

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({FeignClientsRegistrar.class})
public @interface EnableFeignClients {

}

FeignClientsRegistrar实现了ImportBeanDefifinitionRegistrar,它是一个动态注入bean的接口,

Spring Boot启动的时候,会去调用这个类中的registerBeanDefifinitions来实现动态Bean的装载。

它的作用类似于ImportSelector。

class FeignClientsRegistrar
		implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, EnvironmentAware {

	@Override
	public void registerBeanDefinitions(AnnotationMetadata metadata,
			BeanDefinitionRegistry registry) {
		registerDefaultConfiguration(metadata, registry);
		registerFeignClients(metadata, registry);
	}

}

ImportBeanDefifinitionRegistrar

自定义一个自动注入类

  1. 定义一个需要被装载到IOC容器中的类HelloService

public class HelloService {

}

  1. 定义一个Registrar的实现,定义一个bean,装载到IOC容器

public class GpImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar{

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        BeanDefinition beanDefinition=new GenericBeanDefinition();
        beanDefinition.setBeanClassName(HelloService.class.getName());
        registry.registerBeanDefinition("helloService",beanDefinition);
    }
}

  1. 定义一个注解类

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(GpImportBeanDefinitionRegistrar.class)
public @interface EnableGpRegistrara {

}
  1. 写一个测试类

@Configuration
@EnableGpRegistrar
public class TestMain {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(TestMain.class);
        System.out.println(applicationContext.getBean(HelloService.class));
    }
}

通过结果演示可以发现,HelloService这个bean 已经装载到了IOC容器。

这就是动态装载的功能实现,它相比于@Confifiguration配置注入,会多了很多的灵活性。


评论