栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Sping 之 @Import

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Sping 之 @Import

以下都是基于spring-5.2.8,之前的版本可能有所不同

import 是spring中的一个注解,可以用来导入需要实例化的类,把这些类加入spring容器

而且通过import导入进来的类是可以获取到父类上面的注解的信息,当然父类必须要先加入spring管理这个注解能起作用,这个注解是作用于类,接口上面的。

@Component
@import({DeferredimportSelectorDemo.class,SelectimportDemo.class,AwareBean.class})
public class importBean {
}

 Improt注解使用也是很简单的,只需要在注解里面加上需要实例化的类就行了,当然import进来的类也可以实现一些接口。

importSelector,importBeanDefinitionRegistrar两个接口是比较特殊的接口,实现这两个接口的类必须是通过import导入的,这两个接口的方法才会被调用。

 selectimports 方法 入参是导入类的信息,返回值是String数组,数组里面是需要实例化的类的完整限定名  Dome.class.getName()

public class SelectimportDome implements importSelector {
    @Override
    public String[] selectimports(Annotationmetadata importingClassmetadata) {
        MergedAnnotations annotations = importingClassmetadata.getAnnotations();
        MergedAnnotation eas = annotations.get(EnableAspectJAutoProxy.class);

        Object proxyTargetClass = eas.getValue("proxyTargetClass").get();
        //类的完整限定名,
        return new String[]{Dome.class.getName()};
    }
}

@Improt注解是由 ConfigurationClassPostProcessor 处理的 ,这个类实现了 BeanDefinitionRegistryPostProcessor 在spring容器初始的时候会 调用 postProcessBeanDefinitionRegistry ,postProcessBeanFactory这个两个方法

postProcessBeanDefinitionRegistry方法会收集注解,包装注册beanDefinition

这个是具体处理@import注解的方法

具体方法代码

private void processimports(ConfigurationClass configClass, SourceClass currentSourceClass,
			Collection importCandidates, Predicate exclusionFilter,
			boolean checkForCircularimports) {

		//如果没有@import注解直接返回,不处理
		if (importCandidates.isEmpty()) {
			return;
		}

		if (checkForCircularimports && isChainedimportonStack(configClass)) {
			this.problemReporter.error(new CircularimportProblem(configClass, this.importStack));
		}
		else {
			this.importStack.push(configClass);
			try {
				//循环类上面的每一个@import
				for (SourceClass candidate : importCandidates) {
					//如果import进来的是一个importSelector类型
					if (candidate.isAssignable(importSelector.class)) {
						// Candidate class is an importSelector -> delegate to it to determine imports
						Class candidateClass = candidate.loadClass();
						//反射实例化
						importSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, importSelector.class,
								this.environment, this.resourceLoader, this.registry);
						Predicate selectorFilter = selector.getExclusionFilter();
						if (selectorFilter != null) {
							exclusionFilter = exclusionFilter.or(selectorFilter);
						}
						//如果是一个DeferredimportSelector类型
						if (selector instanceof DeferredimportSelector) {
							//比较复杂,springboot中自动配置用到了
							this.deferredimportSelectorHandler.handle(configClass, (DeferredimportSelector) selector);
						}
						else {
							//在这里调用selectimports方法,返回所有的需要import到spring容器的beanName
							String[] importClassNames = selector.selectimports(currentSourceClass.getmetadata());
							Collection importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
							//递归处理,有可能import进来的类又有@import注解
							processimports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
						}
					}
					//如果import进来的是一个importBeanDefinitionRegistrar类型
					else if (candidate.isAssignable(importBeanDefinitionRegistrar.class)) {
						// Candidate class is an importBeanDefinitionRegistrar ->
						// delegate to it to register additional bean definitions
						Class candidateClass = candidate.loadClass();
						//反射实例化
						importBeanDefinitionRegistrar registrar =
								ParserStrategyUtils.instantiateClass(candidateClass, importBeanDefinitionRegistrar.class,
										this.environment, this.resourceLoader, this.registry);
						//加入到importBeanDefinitionRegistrars容器中,这里还没有调用registerBeanDefinitions
						configClass.addimportBeanDefinitionRegistrar(registrar, currentSourceClass.getmetadata());
					}
					else {
						// Candidate class not an importSelector or importBeanDefinitionRegistrar ->
						// process it as an @Configuration class
						this.importStack.registerimport(
								currentSourceClass.getmetadata(), candidate.getmetadata().getClassName());
						//如果都不是,则走这里
						processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
					}
				}
			}
			catch (BeanDefinitionStoreException ex) {
				throw ex;
			}
			catch (Throwable ex) {
				throw new BeanDefinitionStoreException(
						"Failed to process import candidates for configuration class [" +
						configClass.getmetadata().getClassName() + "]", ex);
			}
			finally {
				this.importStack.pop();
			}
		}
	}

1. import 引入没有实现importSelector,importBeanDefinitionRegistrar接口的类会直接解析这个类

2.  1).如果是实现了importSelector 接口的类 就会反射实例化,然后调用selectimports方法

      2).如果是实现了DeferredimportSelector 接口,会调到 DeferredimportSelectorGrouping里面的selectimports方法

其实获取方式还是importSelector 的selectimports

DeferredimportSelectorGrouping 也可以是自己实现的

 如果没有自己实现就是走默认的

3. 实现了importBeanDefinitionRegistrar 接口的,会先加入importBeanDefinitionRegistrars map里面,然后处理

 

 

 

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/324506.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号