动态代理 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 package  cn.idea360.bridge.proxy;import  cn.idea360.bridge.api.UserService;import  cn.idea360.bridge.api.UserServiceImpl;import  cn.idea360.bridge.model.User;import  lombok.extern.slf4j.Slf4j;import  org.junit.jupiter.api.BeforeEach;import  org.junit.jupiter.api.Test;import  org.springframework.cglib.proxy.Enhancer;import  org.springframework.cglib.proxy.MethodInterceptor;import  org.springframework.cglib.proxy.MethodProxy;import  java.lang.reflect.InvocationHandler;import  java.lang.reflect.Method;import  java.lang.reflect.Proxy;@Slf4j public  class  ProxyTest   {    UserService userService;     @BeforeEach      void  init ()  throws  Exception  {         userService = new  UserServiceImpl();     }     @Test      void  dynamicProxy ()  throws  Exception  {         UserService instance = (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), new  InvocationHandler() {             @Override              public  Object invoke (Object proxy, Method method, Object[] args)  throws  Throwable  {                 return  method.invoke(userService, args);             }         });         User user = instance.getUserById(1L );         log.info(user.toString());     }     @Test      void  cglibProxy ()  throws  Exception  {         Enhancer enhancer = new  Enhancer();         enhancer.setSuperclass(userService.getClass());         enhancer.setCallback(new  MethodInterceptor() {             @Override              public  Object intercept (Object o, Method method, Object[] args, MethodProxy methodProxy)  throws  Throwable  {                 return  method.invoke(userService, args);             }         });         UserService instance = (UserService) enhancer.create();         User user = instance.getUserById(1L );         log.info(user.toString());     } } 
 
  简单注入 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 <?xml version="1.0" encoding="UTF-8"?> <project  xmlns ="http://maven.apache.org/POM/4.0.0"  xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"           xsi:schemaLocation ="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" >     <modelVersion > 4.0.0</modelVersion >      <groupId > cn.idea360</groupId >      <artifactId > http-bridge-dubbo</artifactId >      <version > 0.0.1-SNAPSHOT</version >      <name > http-bridge-dubbo</name >      <description > http-bridge-dubbo</description >      <properties >          <java.version > 1.8</java.version >          <project.build.sourceEncoding > UTF-8</project.build.sourceEncoding >          <project.reporting.outputEncoding > UTF-8</project.reporting.outputEncoding >          <spring-boot.version > 2.6.13</spring-boot.version >      </properties >      <dependencies >          <dependency >              <groupId > org.springframework.boot</groupId >              <artifactId > spring-boot-starter-web</artifactId >          </dependency >          <dependency >              <groupId > org.projectlombok</groupId >              <artifactId > lombok</artifactId >              <optional > true</optional >          </dependency >          <dependency >              <groupId > org.springframework.boot</groupId >              <artifactId > spring-boot-starter-test</artifactId >              <scope > test</scope >          </dependency >          <dependency >              <groupId > cn.idea360</groupId >              <artifactId > dubbo-api</artifactId >              <version > 1.0.0</version >          </dependency >      </dependencies >      <dependencyManagement >          <dependencies >              <dependency >                  <groupId > org.springframework.boot</groupId >                  <artifactId > spring-boot-dependencies</artifactId >                  <version > ${spring-boot.version}</version >                  <type > pom</type >                  <scope > import</scope >              </dependency >          </dependencies >      </dependencyManagement >      <build >          <plugins >              <plugin >                  <groupId > org.apache.maven.plugins</groupId >                  <artifactId > maven-compiler-plugin</artifactId >                  <version > 3.8.1</version >                  <configuration >                      <source > 1.8</source >                      <target > 1.8</target >                      <encoding > UTF-8</encoding >                  </configuration >              </plugin >              <plugin >                  <groupId > org.springframework.boot</groupId >                  <artifactId > spring-boot-maven-plugin</artifactId >                  <version > ${spring-boot.version}</version >                  <configuration >                      <mainClass > cn.idea360.bridge.Application</mainClass >                      <skip > true</skip >                  </configuration >                  <executions >                      <execution >                          <id > repackage</id >                          <goals >                              <goal > repackage</goal >                          </goals >                      </execution >                  </executions >              </plugin >          </plugins >      </build >  </project > 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 package  cn.idea360.bridge.support;import  cn.idea360.bridge.proxy.ProxyClient;import  lombok.extern.slf4j.Slf4j;import  org.springframework.beans.BeansException;import  org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;import  org.springframework.beans.factory.config.BeanDefinition;import  org.springframework.beans.factory.config.ConfigurableListableBeanFactory;import  org.springframework.beans.factory.support.BeanDefinitionBuilder;import  org.springframework.beans.factory.support.BeanDefinitionRegistry;import  org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;import  org.springframework.beans.factory.support.GenericBeanDefinition;import  org.springframework.context.EnvironmentAware;import  org.springframework.context.ResourceLoaderAware;import  org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;import  org.springframework.core.env.Environment;import  org.springframework.core.io.ResourceLoader;import  org.springframework.core.type.filter.AnnotationTypeFilter;import  org.springframework.stereotype.Component;import  org.springframework.util.ClassUtils;import  java.util.LinkedHashSet;@Component @Slf4j public  class  ServiceBeanDefinitionRegistry  implements  BeanDefinitionRegistryPostProcessor , ResourceLoaderAware , EnvironmentAware   {    private  ResourceLoader resourceLoader;     private  Environment environment;     @Override      public  void  postProcessBeanDefinitionRegistry (BeanDefinitionRegistry registry)  throws  BeansException  {         log.info("postProcessBeanDefinitionRegistry" );         LinkedHashSet<BeanDefinition> candidateComponents = new  LinkedHashSet<>();         ClassPathScanningCandidateComponentProvider scanner = getScanner();         scanner.setResourceLoader(this .resourceLoader);         scanner.addIncludeFilter(new  AnnotationTypeFilter(ProxyClient.class));                  candidateComponents.addAll(scanner.findCandidateComponents("cn.idea360" ));         candidateComponents.addAll(scanner.findCandidateComponents("com.idea360" ));         for  (BeanDefinition candidateComponent : candidateComponents) {             String className = candidateComponent.getBeanClassName();             log.info("@ProxyClient className: {}" , className);             Class beanClazz = ClassUtils.resolveClassName(className, null );             BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(beanClazz);             GenericBeanDefinition definition = (GenericBeanDefinition) builder.getRawBeanDefinition();             definition.getConstructorArgumentValues().addGenericArgumentValue(beanClazz);             definition.setBeanClass(ServiceFactory.class);             definition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_TYPE);             registry.registerBeanDefinition(beanClazz.getSimpleName(), definition);         }     }     @Override      public  void  postProcessBeanFactory (ConfigurableListableBeanFactory configurableListableBeanFactory)  throws  BeansException  {         log.info("postProcessBeanFactory" );     }     @Override      public  void  setResourceLoader (ResourceLoader resourceLoader)   {         this .resourceLoader = resourceLoader;     }     protected  ClassPathScanningCandidateComponentProvider getScanner ()   {         return  new  ClassPathScanningCandidateComponentProvider(false , this .environment) {             @Override              protected  boolean  isCandidateComponent (AnnotatedBeanDefinition beanDefinition)   {                 boolean  isCandidate = false ;                 if  (beanDefinition.getMetadata().isIndependent()) {                     if  (!beanDefinition.getMetadata().isAnnotation()) {                         isCandidate = true ;                     }                 }                 return  isCandidate;             }         };     }     @Override      public  void  setEnvironment (Environment environment)   {         this .environment = environment;     } } 
 
工厂bean+动态代理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 package  cn.idea360.bridge.support;import  cn.idea360.bridge.model.User;import  lombok.extern.slf4j.Slf4j;import  org.springframework.beans.factory.FactoryBean;import  java.lang.reflect.InvocationHandler;import  java.lang.reflect.Method;import  java.lang.reflect.Proxy;public  class  ServiceFactory <T > implements  FactoryBean <T >  {    private  Class<T> interfaceType;     public  ServiceFactory (Class<T> interfaceType)   {         this .interfaceType = interfaceType;     }     @Override      public  T getObject ()  throws  Exception  {         InvocationHandler handler = new  ServiceProxy<>(interfaceType);         return  (T) Proxy.newProxyInstance(interfaceType.getClassLoader(),                 new  Class[] {interfaceType},handler);     }     @Override      public  Class<?> getObjectType() {         return  interfaceType;     }     @Override      public  boolean  isSingleton ()   {         return  true ;     }     @Slf4j      static  class  ServiceProxy <T > implements  InvocationHandler   {         private  final  Class<T> interfaceType;         public  ServiceProxy (Class<T> interfaceType)   {             this .interfaceType = interfaceType;         }         @Override          public  Object invoke (Object proxy, Method method, Object[] args)  throws  Throwable  {             if  (Object.class.equals(method.getDeclaringClass())) {                 return  method.invoke(this ,args);             }             log.info("interface: {}" , interfaceType);             log.info("method: {}" , method.getName());             log.info("parameterTypes: {}" , method.getParameterTypes());                          log.info("args: {}" , args);             User user = User.builder().name("当我遇上你" ).password("123" ).build();             return  user;         }     } } 
 
单元测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package  cn.idea360.bridge;import  cn.idea360.bridge.api.Role;import  cn.idea360.bridge.api.RoleService;import  cn.idea360.bridge.api.UserService;import  cn.idea360.bridge.model.User;import  lombok.extern.slf4j.Slf4j;import  org.junit.jupiter.api.Test;import  org.springframework.boot.test.context.SpringBootTest;import  javax.annotation.Resource;@Slf4j @SpringBootTest class  ApplicationTests   {    @Resource      private  UserService userService;     @Resource      private  RoleService roleService;     @Test      void  contextLoads ()   {         log.info("app start" );         User user = userService.getUserById(1L );         log.info(user.toString());         roleService.addRole(Role.builder().name("ROLE_ADMIN" ).build());     } } 
 
  参考Feign实现 
org.mybatis.spring.annotation.MapperScan 类似
 
  maven 
1 2 3 4 5 <dependency >     <groupId > org.springframework.cloud</groupId >      <artifactId > spring-cloud-starter-openfeign</artifactId >      <version > 3.0.4</version >  </dependency > 
 
  入口类 
1 org.springframework.cloud.openfeign.EnableFeignClients 
 
  自定义实现 
定义注解 
1 2 3 4 5 6 7 8 9 10 11 12 package  cn.idea360.bridge.proxy;import  java.lang.annotation.*;@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public  @interface  ProxyClient {    String value ()  default  "" ; } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package  cn.idea360.bridge.config;import  org.springframework.context.annotation.Import;import  java.lang.annotation.*;@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Documented @Import({HttpClientsRegistrar.class}) public  @interface  EnableProxy {    String[] value() default  {};     String[] basePackages() default  {};     Class<?>[] basePackageClasses() default  {}; } 
 
注册Bean 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 package  cn.idea360.bridge.config;import  cn.idea360.bridge.proxy.ProxyClient;import  lombok.extern.slf4j.Slf4j;import  org.springframework.beans.factory.FactoryBean;import  org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;import  org.springframework.beans.factory.config.BeanDefinition;import  org.springframework.beans.factory.config.ConfigurableBeanFactory;import  org.springframework.beans.factory.support.AbstractBeanDefinition;import  org.springframework.beans.factory.support.BeanDefinitionBuilder;import  org.springframework.beans.factory.support.BeanDefinitionRegistry;import  org.springframework.context.EnvironmentAware;import  org.springframework.context.ResourceLoaderAware;import  org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;import  org.springframework.context.annotation.ImportBeanDefinitionRegistrar;import  org.springframework.core.env.Environment;import  org.springframework.core.io.ResourceLoader;import  org.springframework.core.type.AnnotationMetadata;import  org.springframework.core.type.filter.AnnotationTypeFilter;import  org.springframework.util.Assert;import  org.springframework.util.ClassUtils;import  org.springframework.util.StringUtils;import  java.util.HashSet;import  java.util.LinkedHashSet;import  java.util.Map;import  java.util.Set;@Slf4j public  class  HttpClientsRegistrar  implements  ImportBeanDefinitionRegistrar , ResourceLoaderAware , EnvironmentAware   {    private  ResourceLoader resourceLoader;     private  Environment environment;     @Override      public  void  setEnvironment (Environment environment)   {         this .environment = environment;     }     @Override      public  void  setResourceLoader (ResourceLoader resourceLoader)   {         this .resourceLoader = resourceLoader;     }     @Override      public  void  registerBeanDefinitions (AnnotationMetadata metadata, BeanDefinitionRegistry registry)   {         LinkedHashSet<BeanDefinition> candidateComponents = new  LinkedHashSet<>();         ClassPathScanningCandidateComponentProvider scanner = getScanner();         scanner.setResourceLoader(this .resourceLoader);         scanner.addIncludeFilter(new  AnnotationTypeFilter(ProxyClient.class));         Set<String> basePackages = getBasePackages(metadata);         for  (String basePackage : basePackages) {             candidateComponents.addAll(scanner.findCandidateComponents(basePackage));         }         for  (BeanDefinition candidateComponent : candidateComponents) {             if  (candidateComponent instanceof  AnnotatedBeanDefinition) {                                  AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent;                 AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();                 Assert.isTrue(annotationMetadata.isInterface(), "@ProxyClient can only be specified on an interface" );                 Map<String, Object> attributes = annotationMetadata                         .getAnnotationAttributes(ProxyClient.class.getCanonicalName());                 registerProxyClient(registry, annotationMetadata, attributes);             }         }     }     private  void  registerProxyClient (BeanDefinitionRegistry registry, AnnotationMetadata annotationMetadata, Map<String, Object> attributes)   {         String className = annotationMetadata.getClassName();         log.info("@ProxyClient className: {}" , className);         Class clazz = ClassUtils.resolveClassName(className, null );         ConfigurableBeanFactory beanFactory = registry instanceof  ConfigurableBeanFactory                 ? (ConfigurableBeanFactory) registry : null ;         ProxyClientFactoryBean factoryBean = new  ProxyClientFactoryBean();         factoryBean.setBeanFactory(beanFactory);         factoryBean.setType(clazz);         BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(clazz, () -> {             return  factoryBean.getObject();         });         definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);         definition.setLazyInit(true );         AbstractBeanDefinition beanDefinition = definition.getBeanDefinition();         beanDefinition.setAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE, className);         registry.registerBeanDefinition(className, beanDefinition);     }     protected  ClassPathScanningCandidateComponentProvider getScanner ()   {         return  new  ClassPathScanningCandidateComponentProvider(false , this .environment) {             @Override              protected  boolean  isCandidateComponent (AnnotatedBeanDefinition beanDefinition)   {                 boolean  isCandidate = false ;                 if  (beanDefinition.getMetadata().isIndependent()) {                     if  (!beanDefinition.getMetadata().isAnnotation()) {                         isCandidate = true ;                     }                 }                 return  isCandidate;             }         };     }     protected  Set<String> getBasePackages (AnnotationMetadata importingClassMetadata)   {         Map<String, Object> attributes = importingClassMetadata                 .getAnnotationAttributes(EnableProxy.class.getCanonicalName());         Set<String> basePackages = new  HashSet<>();         for  (String pkg : (String[]) attributes.get("value" )) {             if  (StringUtils.hasText(pkg)) {                 basePackages.add(pkg);             }         }         for  (String pkg : (String[]) attributes.get("basePackages" )) {             if  (StringUtils.hasText(pkg)) {                 basePackages.add(pkg);             }         }         for  (Class<?> clazz : (Class[]) attributes.get("basePackageClasses" )) {             basePackages.add(ClassUtils.getPackageName(clazz));         }         if  (basePackages.isEmpty()) {             basePackages.add(ClassUtils.getPackageName(importingClassMetadata.getClassName()));         }         return  basePackages;     } } 
 
接口工厂Bean 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 package  cn.idea360.bridge.config;import  org.springframework.beans.BeansException;import  org.springframework.beans.factory.BeanFactory;import  org.springframework.beans.factory.BeanFactoryAware;import  org.springframework.beans.factory.FactoryBean;import  org.springframework.beans.factory.InitializingBean;import  org.springframework.context.ApplicationContext;import  org.springframework.context.ApplicationContextAware;import  java.lang.reflect.InvocationHandler;import  java.lang.reflect.Proxy;public  class  ProxyClientFactoryBean  implements  FactoryBean <Object >, InitializingBean , ApplicationContextAware , BeanFactoryAware   {    private  Class<?> type;     private  BeanFactory beanFactory;     private  ApplicationContext applicationContext;     @Override      public  Object getObject ()   {         InvocationHandler handler = new  ServiceProxy<>(type);         return  Proxy.newProxyInstance(type.getClassLoader(),                 new  Class[] {type}, handler);     }     @Override      public  Class<?> getObjectType() {         return  type;     }     @Override      public  boolean  isSingleton ()   {         return  true ;     }     public  void  setType (Class<?> type)   {         this .type = type;     }     public  Class<?> getType() {         return  type;     }     @Override      public  void  setBeanFactory (BeanFactory beanFactory)  throws  BeansException  {         this .beanFactory = beanFactory;     }     @Override      public  void  afterPropertiesSet ()  throws  Exception  {     }     @Override      public  void  setApplicationContext (ApplicationContext context)  throws  BeansException  {         applicationContext = context;         beanFactory = context;     } } 
 
动态代理 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 package  cn.idea360.bridge.config;import  cn.idea360.bridge.model.User;import  lombok.extern.slf4j.Slf4j;import  java.lang.reflect.InvocationHandler;import  java.lang.reflect.Method;@Slf4j public  class  ServiceProxy <T > implements  InvocationHandler   {    private  final  Class<T> interfaceType;     public  ServiceProxy (Class<T> interfaceType)   {         this .interfaceType = interfaceType;     }     @Override      public  Object invoke (Object proxy, Method method, Object[] args)  throws  Throwable  {         if  (Object.class.equals(method.getDeclaringClass())) {             return  method.invoke(this ,args);         }         log.info("interface: {}" , interfaceType);         log.info("method: {}" , method.getName());         log.info("parameterTypes: {}" , method.getParameterTypes());                  log.info("args: {}" , args);         User user = User.builder().name("当我遇上你" ).password("123" ).build();         return  user;     } } 
 
接口定义 
1 2 3 4 5 @ProxyClient public  interface  UserService   {    User getUserById (Long id)  ; } 
 
启动类 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package  cn.idea360.bridge;import  cn.idea360.bridge.config.EnableProxy;import  org.springframework.boot.SpringApplication;import  org.springframework.boot.autoconfigure.SpringBootApplication;@EnableProxy(value = {"cn.idea360", "com.idea360"}) @SpringBootApplication public  class  Application   {    public  static  void  main (String[] args)   {         SpringApplication.run(Application.class, args);     } } 
 
  常用操作 
扫描包含注解的component 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public  Set<String> findAnnotatedClasses (Class<? extends Annotation> annotationType, String... packagesToBeScanned)   {    ClassPathScanningCandidateComponentProvider provider = new  ClassPathScanningCandidateComponentProvider(false );     provider.addIncludeFilter(new  AnnotationTypeFilter(annotationType));     Set<String> ret = new  HashSet<>();     for  (String pkg : packagesToBeScanned)     {         Set<BeanDefinition> beanDefs = provider.findCandidateComponents(pkg);         beanDefs.stream()                 .map(BeanDefinition::getBeanClassName)                 .forEach(ret::add);     }     return  ret; } 
 
扫描包含三方jar的class 
1 2 3 4 5 <dependency >     <groupId > cn.hutool</groupId >      <artifactId > hutool-all</artifactId >      <version > 5.5.0</version >  </dependency > 
 
1 2 3 4 5 @Test void  scans ()   {    Set<Class<?>> classes = ClassScanner.scanPackage("cn.idea360" );     log.info("@ProxyClient {}" , classes.contains(RoleService.class)); } 
 
  BeanDefinitionRegistryPostProcessor 和ImportBeanDefinitionRegistrar 有什么区别 
BeanDefinitionRegistryPostProcessor 和 ImportBeanDefinitionRegistrar 都是用于动态注册 Bean 到 Spring 容器的接口,但它们的使用场景和目的略有不同。
BeanDefinitionRegistryPostProcessor: :
作用:在 Spring 容器加载 Bean 定义之后,但在实例化 Bean 之前,允许对 BeanDefinition 进行修改或者注册新的 BeanDefinition。 
使用场景:适用于在应用启动时对现有 BeanDefinition 进行修改或者添加一些新的 BeanDefinition。 
例子:用于动态注册数据源、JdbcTemplate、事务管理器等。 
 
ImportBeanDefinitionRegistrar: 
作用:允许在配置类中根据条件动态注册额外的 BeanDefinition。 
使用场景:适用于根据特定条件选择性地注册 BeanDefinition。通常与 @Import 注解一起使用,以实现特定的条件化配置。 
例子:用于基于某些条件选择性地注册一些 Bean。@Enablexxx 
 
选择哪个更适合注册多数据源 
如果你的主要目标是在应用启动时动态注册多个数据源,那么使用 BeanDefinitionRegistryPostProcessor 更为直观和合适。 
如果你需要在配置类中根据条件来动态选择性地注册一些 Bean,那么 ImportBeanDefinitionRegistrar 可能更适合,尤其是当你希望将注册逻辑放在配置类中时。 
 
在注册多数据源的场景中,通常会使用 BeanDefinitionRegistryPostProcessor,因为你可以在这个时机处理数据源的注册,而且这是一个更自然的选择。