javascript
Spring 通过@Import实现Bean的注册
今天看到一個神奇的用法, Spring可以通過@Import導入實現了ImportBeanDefinitionRegistrar接口的類來注冊那個類.
ImportBeanDefinitionRegistrar接口是用來被實現以使Spring在處理Configuration的時候注冊額外的bean. @Import注解可以引入一個Configuration類, 或ImportSelector實現類以根據特定條件導入合適的類. 其次就是可以引入實現了ImportBeanDefinitionRegistrar接口的類來直接注冊類.
當然, 除了ImportBeanDefinitionRegistrar實現類, 還可以使用ClassPathBeanDefinitionScanner這個掃描器, 獲取需要注冊的bean. ClassPathBeanDefinitionScanner繼承了ClassPathScanningCandidateComponentProvider, 其中有兩個TypeFilter, includeFilters和excludeFilters, 可以用來過濾類.
比如以下即實現了ImportBeanDefinitionRegistrar接口:
class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, EnvironmentAware {public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {this.registerDefaultConfiguration(metadata, registry);this.registerFeignClients(metadata, registry);} }在registerFeignClients使用ClassPathScanningCandidateComponentProvider來過濾類, 注入包含了@FeignClient注解的類.
public void registerFeignClients(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {ClassPathScanningCandidateComponentProvider scanner = this.getScanner();scanner.setResourceLoader(this.resourceLoader);Map<String, Object> attrs = metadata.getAnnotationAttributes(EnableFeignClients.class.getName());AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter(FeignClient.class);Class<?>[] clients = attrs == null ? null : (Class[])((Class[])attrs.get("clients"));Object basePackages;if (clients != null && clients.length != 0) {final Set<String> clientClasses = new HashSet();basePackages = new HashSet();Class[] var9 = clients;int var10 = clients.length;for(int var11 = 0; var11 < var10; ++var11) {Class<?> clazz = var9[var11];((Set)basePackages).add(ClassUtils.getPackageName(clazz));clientClasses.add(clazz.getCanonicalName());}AbstractClassTestingTypeFilter filter = new AbstractClassTestingTypeFilter() {protected boolean match(ClassMetadata metadata) {String cleaned = metadata.getClassName().replaceAll("\\$", ".");return clientClasses.contains(cleaned);}};scanner.addIncludeFilter(new FeignClientsRegistrar.AllTypeFilter(Arrays.asList(filter, annotationTypeFilter)));} else {scanner.addIncludeFilter(annotationTypeFilter);basePackages = this.getBasePackages(metadata);}Iterator var17 = ((Set)basePackages).iterator();while(var17.hasNext()) {String basePackage = (String)var17.next();Set<BeanDefinition> candidateComponents = scanner.findCandidateComponents(basePackage);Iterator var21 = candidateComponents.iterator();while(var21.hasNext()) {BeanDefinition candidateComponent = (BeanDefinition)var21.next();if (candidateComponent instanceof AnnotatedBeanDefinition) {AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition)candidateComponent;AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();Assert.isTrue(annotationMetadata.isInterface(), "@FeignClient can only be specified on an interface");Map<String, Object> attributes = annotationMetadata.getAnnotationAttributes(FeignClient.class.getCanonicalName());String name = this.getClientName(attributes);this.registerClientConfiguration(registry, name, attributes.get("configuration"));this.registerFeignClient(registry, annotationMetadata, attributes);}}}}轉載于:https://www.cnblogs.com/helloz/p/11266358.html
總結
以上是生活随笔為你收集整理的Spring 通过@Import实现Bean的注册的全部內容,希望文章能夠幫你解決所遇到的問題。