代码入口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的作用前面的文章专门简绍了。连接奉上。
CSDNhttps://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此方法就我们在自动装配一文中详细的分析过。