ImportSelector和ImportBeanDefinitionRegistrar两种注入方式的源码分析

 代码入口processImports方法

说明:带有 @Configuration 的配置类(4.2 版本之前只可以导入配置类,4.2 版本之后也可以导入普通类

org.springframework.context.annotation.ConfigurationClassParser 这个配置类的解析类中的

processImports方法源代码如下:
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
			Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
			boolean checkForCircularImports) {

		if (importCandidates.isEmpty()) {
			return;
		}

		if (checkForCircularImports && isChainedImportOnStack(configClass)) {
			this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
		}
		else {
			this.importStack.push(configClass);
			try {
				for (SourceClass candidate : importCandidates) {

//处理@Import注解中的ImportSelector.class
					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<String> selectorFilter = selector.getExclusionFilter();
						if (selectorFilter != null) {
							exclusionFilter = exclusionFilter.or(selectorFilter);
						}
						if (selector instanceof DeferredImportSelector) {
//AutoConfigurationImportSelector(自动装配)实现了DeferredImportSelector接口所以需要添加到DeferredImportSelectorHandler中的deferredImportSelectors属性中。这是个list
							this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
						}
						else {
							String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
							Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
							processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
						}
					}

//处理@Import注解中的ImportBeanDefinitionRegistrar.class

					else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
						// Candidate class is an ImportBeanDefinitionRegistrar ->
						// delegate to it to register additional bean definitions
						Class<?> candidateClass = candidate.loadClass();
//首先实例化ImportBeanDefinitionRegistrar
						ImportBeanDefinitionRegistrar registrar =
								ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
										this.environment, this.resourceLoader, this.registry);
//添加到配置类的封装类ConfigurationClass的importBeanDefinitionRegistrars属性 是个LinkedHashMap中
						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();
			}
		}
	}

关于ImportSelector和ImportBeanDefinitionRegistrar.class的作用前面的文章专门简绍了。连接奉上。

CSDNicon-default.png?t=N7T8https://mp.csdn.net/mp_blog/creation/editor/131975839

ImportBeanDefinitionRegistrar

一,实例化过程

首先创建ImportBeanDefinitionRegistrar对象,使用spring内部最常用的创建对象的方式,spring绝大部分的bean产生对象的方式,是bean生命周期的关键部分。@ComponentScan注解扫描出来的类也是通过这个方法生成的对象,进而生成Bean.

ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
      this.environment, this.resourceLoader, this.registry);

我们进入方法内部继续分析

static <T> T instantiateClass(Class<?> clazz, Class<T> assignableTo, Environment environment,
			ResourceLoader resourceLoader, BeanDefinitionRegistry registry) {

		Assert.notNull(clazz, "Class must not be null");
		Assert.isAssignable(assignableTo, clazz);
		if (clazz.isInterface()) {
			throw new BeanInstantiationException(clazz, "Specified class is an interface");
		}
		ClassLoader classLoader = (registry instanceof ConfigurableBeanFactory ?
				((ConfigurableBeanFactory) registry).getBeanClassLoader() : resourceLoader.getClassLoader());
		T instance = (T) createInstance(clazz, environment, resourceLoader, registry, classLoader);
		ParserStrategyUtils.invokeAwareMethods(instance, environment, resourceLoader, registry, classLoader);
		return instance;
	}

	private static Object createInstance(Class<?> clazz, Environment environment,
			ResourceLoader resourceLoader, BeanDefinitionRegistry registry,
			@Nullable ClassLoader classLoader) {

		Constructor<?>[] constructors = clazz.getDeclaredConstructors();
    //有一个有参构造函数走此逻辑
		if (constructors.length == 1 && constructors[0].getParameterCount() > 0) {
			try {
				Constructor<?> constructor = constructors[0];
				Object[] args = resolveArgs(constructor.getParameterTypes(),
						environment, resourceLoader, registry, classLoader);
				return BeanUtils.instantiateClass(constructor, args);
			}
			catch (Exception ex) {
				throw new BeanInstantiationException(clazz, "No suitable constructor found", ex);
			}
		}
//默认使用无参构造函数通过反射创建对象
		return BeanUtils.instantiateClass(clazz);
	}

我们可以看到默认就是走BeanUtils.instantiateClass(clazz)无参构造函数创建对象。

接下来我们进入instantiateClass方法内部分析:

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
        Assert.notNull(ctor, "Constructor must not be null");

        try {
            ReflectionUtils.makeAccessible(ctor);
            if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
                return BeanUtils.KotlinDelegate.instantiateClass(ctor, args);
            } else {
                Class<?>[] parameterTypes = ctor.getParameterTypes();
                Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
                Object[] argsWithDefaultValues = new Object[args.length];

                for(int i = 0; i < args.length; ++i) {
                    if (args[i] == null) {
                        Class<?> parameterType = parameterTypes[i];
                        argsWithDefaultValues[i] = parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null;
                    } else {
                        argsWithDefaultValues[i] = args[i];
                    }
                }
//最终看到是通过反射创建的对象
                return ctor.newInstance(argsWithDefaultValues);
            }
        } catch (InstantiationException var6) {
            throw new BeanInstantiationException(ctor, "Is it an abstract class?", var6);
        } catch (IllegalAccessException var7) {
            throw new BeanInstantiationException(ctor, "Is the constructor accessible?", var7);
        } catch (IllegalArgumentException var8) {
            throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", var8);
        } catch (InvocationTargetException var9) {
            throw new BeanInstantiationException(ctor, "Constructor threw exception", var9.getTargetException());
        }
    }

ImportSelector

实例化过程同上。此处不再赘述。

ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,
								this.environment, this.resourceLoader, this.registry);

 我们看到AutoConfigurationImportSelector实现了DeferredImportSelector

public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
		ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

我们回到解析方法中:

this.deferredImportSelectorHandler.process();这行代码就是要处理自动配置的入口。
public void process() {
			List<DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors;
			this.deferredImportSelectors = null;
			try {
				if (deferredImports != null) {
					DeferredImportSelectorGroupingHandler handler = new DeferredImportSelectorGroupingHandler();
					deferredImports.sort(DEFERRED_IMPORT_COMPARATOR);
					deferredImports.forEach(handler::register);
//这个是关键代码以Group的身份处理
					handler.processGroupImports();
				}
			}
			finally {
				this.deferredImportSelectors = new ArrayList<>();
			}
		}
	}
public void processGroupImports() {
			for (DeferredImportSelectorGrouping grouping : this.groupings.values()) {
				Predicate<String> exclusionFilter = grouping.getCandidateFilter();
			//getImports内部通过调用process方法,而不是selectorImport方法,需要特别注意
grouping.getImports().forEach(entry -> {
					ConfigurationClass configurationClass = this.configurationClasses.get(entry.getMetadata());
					try {
						processImports(configurationClass, asSourceClass(configurationClass, exclusionFilter),
								Collections.singleton(asSourceClass(entry.getImportClassName(), exclusionFilter)),
								exclusionFilter, false);
					}
					catch (BeanDefinitionStoreException ex) {
						throw ex;
					}
					catch (Throwable ex) {
						throw new BeanDefinitionStoreException(
								"Failed to process import candidates for configuration class [" +
										configurationClass.getMetadata().getClassName() + "]", ex);
					}
				});
			}
		}

getImports内部通过调用process方法,而不是selectorImport方法,需要特别注意

public Iterable<Group.Entry> getImports() {
			for (DeferredImportSelectorHolder deferredImport : this.deferredImports) {

// group的实现类是AutoConfigurationImportSelector类中的内部类AutoConfigurationGroup,
//process方法的第二个入参deferredImport.getImportSelector()这个就是
//AutoConfigurationImportSelector类的对象,通过该对象调用getAutoConfigurationEntry方法
//getAutoConfigurationEntry此方法就
				this.group.process(deferredImport.getConfigurationClass().getMetadata(),
						deferredImport.getImportSelector());
			}
			return this.group.selectImports();
		}

group的实现类是AutoConfigurationImportSelector类中的内部类AutoConfigurationGroup,
process方法的第二个入参deferredImport.getImportSelector()这个入参就是
AutoConfigurationImportSelector类的对象,通过该对象调用getAutoConfigurationEntry方法,
getAutoConfigurationEntry此方法就我们在自动装配一文中详细的分析过。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值