Spring5.0.x源码分析(二)

3、refresh()

继续看AbstractApplicationContext#refresh()方法,接上节到3.4

3.4 postProcessBeanFactory(beanFactory)

是个空方法

3.5 invokeBeanFactoryPostProcessors(beanFactory)

Invoke factory processors registered as beans in the context,执行bean工厂后置处理器
下面做简单的测试

//定义个类,通过加注解,然后被扫描到加入到容器中,默认为单例
@Repository
public class UserDao {
}

定义MyBeanFactoryProcesser,拿到userDao这个bean在工厂中对应的BeanDefinition,通过BeanDefinition可以拿到关于userDao这个bean在Spring容器中的很多信息,这里我们将其设置为多例

@Component
public class MyBeanFactoryProcesser implements BeanFactoryPostProcessor {
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userDao");
		beanDefinition.setScope("prototype");
	}
}
public class Test {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
		Object dao1 = ac.getBean("userDao");
		Object dao2 = ac.getBean("userDao");
		System.out.println(dao1);
		System.out.println(dao2);
	}
}

可以看到此时的UserDao在容器中已经不是单例的了
在这里插入图片描述
如果注释掉MyBeanFactoryProcesser@Component注解再次运行后,UserDao又是单例的了。

修改测试方法如下

@Configuration
@ComponentScan("com.liaoxiang")
public class AppConfig {

}
public class Test {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
		ac.register(AppConfig.class);
		ac.addBeanFactoryPostProcessor(new MyBeanFactoryProcesser());
		ac.refresh();
		Object dao1 = ac.getBean("userDao");
		Object dao2 = ac.getBean("userDao");
		System.out.println(dao1);
		System.out.println(dao2);
	}
}

此时UserDao又变成多例的了,加断点看一下,从3.5行所在代码直接进入invokeBeanFactoryPostProcessors()方法,定义在AbstractApplicationContext

/**
 * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
 * respecting explicit order if given.
 * <p>Must be called before singleton instantiation.
 * =================================================================================================================!!
 */
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	//第二参数getBeanFactoryPostProcessors()获取的自定义的且没有加注解的bean工厂后置处理器
	PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

	// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
	// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
	if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
		beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
		beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
	}
}

在这里插入图片描述
可以看到getBeanFactoryPostProcessors()获取到的就是没有加注解的自定义处理器,beanFactoryPostProcessorsAbstractApplicationContext的成员变量:

/** BeanFactoryPostProcessors to apply on refresh */
private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();

/**
 * Return the list of BeanFactoryPostProcessors that will get applied
 * to the internal BeanFactory.
 */
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
	return this.beanFactoryPostProcessors;
}

当我们在测试方法中执行:
ac.addBeanFactoryPostProcessor(new MyBeanFactoryProcessor()),实际执行的是AbstractApplicationContext类中下面的方法:

@Override
public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
	Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
	this.beanFactoryPostProcessors.add(postProcessor);
}

如果我们使用的是加了注解的自定义处理器,交由Spring容器来处理,即上面第一次的情况运行到此处的话,其结果如下,getBeanFactoryPostProcessors()方法返回为空,因为在整个过程中并没有向beanFactoryPostProcessors 这个List集合中添加任何的处理器
在这里插入图片描述
在未加注释的情况下(自己new,手动添加)继续执行,进入到:
PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors()方法

final class PostProcessorRegistrationDelegate {

	public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		Set<String> processedBeans = new HashSet<>();
		//这里的beanFactory是DefaultListableBeanFactory对象,它实现了BeanDefinitionRegistry接口
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;

			//存放自定义的BeanFactoryPostProcessor--->MyBeanFactoryPostProcessor
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();

			//BeanDefinitionRegistryPostProcessor已经继承了BeanFactoryPostProcessor接口
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			//循环的是自定义的实现了BeanFactoryPostProcessor接口的类的集合,未加注解
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				/**
				 * 我们定义的处理器处理器实现的是BeanFactoryPostProcessor,所以这个为false
				 * 当我们定义的处理器实现的接口是BeanDefinitionRegistryPostProcessor时,就会进入这个方法
				 * 最后会将自定义的处理器加入到registryProcessors中
				 * BeanDefinitionRegistryPostProcessor接口扩展了BeanFactoryPostProcessor接口
				 * 扩展方法:
				 * 	postProcessBeanDefinitionRegistry
				 */
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				// 将自定义的处理器加入到regularPostProcessors
				else {
					regularPostProcessors.add(postProcessor);
				}
			}
			// Do not initialize FactoryBeans here: We need to leave all regular beans
			// uninitialized to let the bean factory post-processors apply to them!
			// Separate between BeanDefinitionRegistryPostProcessors that implement
			// PriorityOrdered, Ordered, and the rest.
			// currentRegistryProcessors放的spring内部自己的实现了BeanDefinitionRegistryPostProcessor接口的处理器
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			// 排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			// 合并
			registryProcessors.addAll(currentRegistryProcessors);

			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();
			.....
			//省略部分代码

两个Bean工厂后置处理器接口,这是spring的两个扩展点,实现这两个接口就可以插手beanFactory的创建过程(上一节中的BeanPostProcessor也是一个扩展点)

/**
 * Allows for custom modification of an application context's bean definitions,
 * adapting the bean property values of the context's underlying bean factory.
 *
 * <p>Application contexts can auto-detect BeanFactoryPostProcessor beans in
 * their bean definitions and apply them before any other beans get created.
 *
 * <p>Useful for custom config files targeted at system administrators that
 * override bean properties configured in the application context.
 *
 * <p>See PropertyResourceConfigurer and its concrete implementations
 * for out-of-the-box solutions that address such configuration needs.
 *
 * <p>A BeanFactoryPostProcessor may interact with and modify bean
 * definitions, but never bean instances. Doing so may cause premature bean
 * instantiation, violating the container and causing unintended side-effects.
 * If bean instance interaction is required, consider implementing
 * {@link BeanPostProcessor} instead.
 *
 * @author Juergen Hoeller
 * @since 06.07.2003
 * @see BeanPostProcessor
 * @see PropertyResourceConfigurer
 */
@FunctionalInterface
public interface BeanFactoryPostProcessor {

	/**
	 * Modify the application context's internal bean factory after its standard
	 * initialization. All bean definitions will have been loaded, but no beans
	 * will have been instantiated yet. This allows for overriding or adding
	 * properties even to eager-initializing beans.
	 * @param beanFactory the bean factory used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}
/**
 * Extension to the standard {@link BeanFactoryPostProcessor} SPI, allowing for
 * the registration of further bean definitions <i>before</i> regular
 * BeanFactoryPostProcessor detection kicks in. In particular,
 * BeanDefinitionRegistryPostProcessor may register further bean definitions
 * which in turn define BeanFactoryPostProcessor instances.
 *
 * @author Juergen Hoeller
 * @since 3.0.1
 * @see org.springframework.context.annotation.ConfigurationClassPostProcessor
 */
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

	/**
	 * Modify the application context's internal bean definition registry after its
	 * standard initialization. All regular bean definitions will have been loaded,
	 * but no beans will have been instantiated yet. This allows for adding further
	 * bean definitions before the next post-processing phase kicks in.
	 * @param registry the bean definition registry used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}

将我们自定义(以后说自定义都是未加注解,自己显示new出来的)后置处理器加到名为regularPostProcessors的List集合中,(如果自定义的处理器加了注解交由Spring容器实例化,直接跳过for循环)此时for循环执行一次,然后往下执行到beanFactory.getBeanNamesForType()方法,跟进去,进入到DefaultListableBeanFactory类中,这个方法的作用是根据一个类型来拿到所有这个类型的类的类名,BeanDefinition中就描述的有类的类型和BeanName等,这里的这个方法就是在beanFactory中找出类型为BeanDefinitionRegistryPostProcessor.class的所有bean的beanName

// 参数为一个Class 和 两个布尔类型,上面传入的类型并不为null,if判断为true,调用doGetBeanNamesForType
@Override
public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
	if (!isConfigurationFrozen() || type == null || !allowEagerInit) {
		return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit);
	}
	Map<Class<?>, String[]> cache =
			(includeNonSingletons ? this.allBeanNamesByType : this.singletonBeanNamesByType);
	String[] resolvedBeanNames = cache.get(type);
	if (resolvedBeanNames != null) {
		return resolvedBeanNames;
	}
	resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true);
	if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) {
		cache.put(type, resolvedBeanNames);
	}
	return resolvedBeanNames;
}

最后通过这个方法拿到了ConfigurationClassPostProcessor的BeanName,ConfigurationClassPostProcessor这个类是在上一节new AnnotatedBeanDefinitionReader(this)的时候加入到DefaultListableBeanFactory类中的beanDefinitionMap中的,为的就是在spring的beanFactory初始化的过程中去做一些事情,那么到底做哪些事情呢,下面揭晓
在这里插入图片描述
for循环执行完成之后
在这里插入图片描述往下执行到invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 合并,如果我们自定义的处理器实现的是BeanDefinitionRegistryPostProcessor接口,就会加入到registryProcessors中
registryProcessors.addAll(currentRegistryProcessors);
// 此时这里传递的参数只有一个,就是ConfigurationClassPostProcessor对象
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

进入PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors()

/**
 * Invoke the given BeanDefinitionRegistryPostProcessor beans.
 * ==================================================================================================================!!
 */
private static void invokeBeanDefinitionRegistryPostProcessors(
		Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
	/**
	 * 循环所有的实现了BeanDefinitionRegistryPostProcessor接口的处理器
	 * 执行处理器中重写的postProcessBeanDefinitionRegistry()方法
	 */
	for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
		// 循环postProcessors这个List集合,里面就是ConfigurationClassPostProcessor
		// ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor接口
		postProcessor.postProcessBeanDefinitionRegistry(registry);
	}
}

进入ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
到这里就开始执行Bean工厂后置处理器的方法了,这是spring自己的后置处理器,如果我们自己也写了一个后置处理器并且实现的是BeanDefinitionRegistryPostProcessor接口,那么也会在上面的循环中被执行

/**
 * Derive further bean definitions from the configuration classes in the registry.
 */
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
	int registryId = System.identityHashCode(registry);
	if (this.registriesPostProcessed.contains(registryId)) {
		throw new IllegalStateException(
				"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
	}
	if (this.factoriesPostProcessed.contains(registryId)) {
		throw new IllegalStateException(
				"postProcessBeanFactory already called on this post-processor against " + registry);
	}
	this.registriesPostProcessed.add(registryId);

	processConfigBeanDefinitions(registry);
}

进入ConfigurationClassPostProcessor#processConfigBeanDefinitions()
在这里插入图片描述
根据名称拿出工厂中的已存在的所有bd,检查这些bd所描述的类都加有哪些注解
在这里插入图片描述
进入ConfigurationClassUtils#checkConfigurationClassCandidate()

public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
	// 获取className
	String className = beanDef.getBeanClassName();
	if (className == null || beanDef.getFactoryMethodName() != null) {
		return false;
	}

	AnnotationMetadata metadata;
	/**
	 * 是AnnotatedBeanDefinition类型
	 * 判断className和元数据里的className
	 */
	if (beanDef instanceof AnnotatedBeanDefinition &&
			className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) {
		// Can reuse the pre-parsed metadata from the given BeanDefinition...
		// 获得注解原数据
		metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata();
	}
	// 是AbstractBeanDefinition类型
	else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
		// Check already loaded Class if present...
		// since we possibly can't even load the class file for this Class.
		Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
		// 获得注解原数据
		metadata = new StandardAnnotationMetadata(beanClass, true);
	}
	// 不是上面的两种,从metadataReaderFactory中获取
	else {
		try {
			MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
			// 获得注解原数据
			metadata = metadataReader.getAnnotationMetadata();
		}
		catch (IOException ex) {
			if (logger.isDebugEnabled()) {
				logger.debug("Could not find class file for introspecting configuration annotations: " + className, ex);
			}
			return false;
		}
	}
	// 通过元数据判断是否加了 @Configuration注解
	if (isFullConfigurationCandidate(metadata)) {
		// 如果加了就设置FULL属性
		beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
	}
	// 判断是否加了其他四种注解
	else if (isLiteConfigurationCandidate(metadata)) {
		// 如果加了就设置FULL属性
		beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
	}
	else {
		return false;
	}

	// It's a full or lite configuration candidate... Let's determine the order value, if any.
	Integer order = getOrder(metadata);
	if (order != null) {
		//设置order
		beanDef.setAttribute(ORDER_ATTRIBUTE, order);
	}

	return true;
}

isFullConfigurationCandidate(metadata)

/**
 * Check the given metadata for a full configuration class candidate
 * (i.e. a class annotated with {@code @Configuration}).
 * @param metadata the metadata of the annotated class
 * @return {@code true} if the given class is to be processed as a full
 * configuration class, including cross-method call interception
 */
public static boolean isFullConfigurationCandidate(AnnotationMetadata metadata) {
	return metadata.isAnnotated(Configuration.class.getName());
}

isLiteConfigurationCandidate(metadata)

public static boolean isLiteConfigurationCandidate(AnnotationMetadata metadata) {
	// Do not consider an interface or an annotation...
	if (metadata.isInterface()) {
		return false;
	}

	// Any of the typical annotations found?
	for (String indicator : candidateIndicators) {
		if (metadata.isAnnotated(indicator)) {
			return true;
		}
	}

	// Finally, let's look for @Bean methods...
	try {
		return metadata.hasAnnotatedMethods(Bean.class.getName());
	}
	catch (Throwable ex) {
		if (logger.isDebugEnabled()) {
			logger.debug("Failed to introspect @Bean methods on class [" + metadata.getClassName() + "]: " + ex);
		}
		return false;
	}
}

是否被这四个注解注释
在这里插入图片描述
我们这里单独看一下自己写的加了注释的AppConfig类
在这里插入图片描述
在这里插入图片描述
对于AppConfig来说由于加了@Configuration注解,进入isFullConfigurationCandidate判断后,不会进入直isLiteConfigurationCandidate判断,而其他类由于没有@Configuration这个注解会进入isLiteConfigurationCandidate(metadata)方法,在有@Configuration注解的时候,spring会自动检查除了这个注解外是否还有其他注解
在这里插入图片描述
当有Order注解的时候,设置一下order属性后就返回到ConfigurationClassPostProcessor类继续执行。
对于检查过后返回true的BD,会构建一个BeanDefinitionHolder对象,放到一个List集合中:
List<BeanDefinitionHolder> configCandidates
在这里插入图片描述
进入ConfigurationClassParser#parse()方法,将configCandidates传过去

public void parse(Set<BeanDefinitionHolder> configCandidates) {
	this.deferredImportSelectors = new LinkedList<>();
	// 循环set集合,拿出bd
	for (BeanDefinitionHolder holder : configCandidates) {
		BeanDefinition bd = holder.getBeanDefinition();
		try {
			// 判断bd是否是被加了注解的bd
			if (bd instanceof AnnotatedBeanDefinition) {
				// 调用重载的方法
				parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
			}
			else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
				parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
			}
			else {
				parse(bd.getBeanClassName(), holder.getBeanName());
			}
		}
		catch (BeanDefinitionStoreException ex) {
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanDefinitionStoreException(
					"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
		}
	}

	processDeferredImportSelectors();
}

进入ConfigurationClassParser#parse(),将类信息封装成一个ConfigurationClass对象,作为参数
在这里插入图片描述
进入ConfigurationClassParser#processConfigurationClass()
在这里插入图片描述
进入ConfigurationClassParser#doProcessConfigurationClass(),在这个方法中,就在处理各种注解

// Recursively process any member (nested) classes first,处理内部类
// Process any @PropertySource annotations,处理 @PropertySource注解
// Process any @ComponentScan annotations,处理 @ComponentScan注解
// Process any @Import annotations, 处理 @Import 注解
// Process any @ImportResource annotations,处理 @ImportResource注解
// Process individual @Bean methods,处理单个@Bean方法
// Process superclass, if any  处理父类

方法如下:

/**
 * Apply processing and build a complete {@link ConfigurationClass} by reading the
 * annotations, members and methods from the source class. This method can be called
 * multiple times as relevant sources are discovered.
 * @param configClass the configuration class being build
 * @param sourceClass a source class
 * @return the superclass, or {@code null} if none found or previously processed
 */
@Nullable
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
		throws IOException {

	// Recursively process any member (nested) classes first,处理内部类
	processMemberClasses(configClass, sourceClass);

	// Process any @PropertySource annotations,处理 @PropertySource注解
	for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
					sourceClass.getMetadata(), PropertySources.class,
					org.springframework.context.annotation.PropertySource.class)) {
		if (this.environment instanceof ConfigurableEnvironment) {
			processPropertySource(propertySource);
		}
		else {
			logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
					"]. Reason: Environment must implement ConfigurableEnvironment");
		}
	}

	// Process any @ComponentScan annotations,处理 @ComponentScan注解
	Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
			sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
	if (!componentScans.isEmpty() &&
			!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
		//循环解析 @ComponentScan注解中的属性值
		for (AnnotationAttributes componentScan : componentScans) {
			// The config class is annotated with @ComponentScan -> perform the scan immediately
			Set<BeanDefinitionHolder> scannedBeanDefinitions =
					this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
			// Check the set of scanned definitions for any further config classes and parse recursively if needed
			//检查已扫描的定义集以获得更多的配置类,并在需要时进行递归解析
			for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
				BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
				if (bdCand == null) {
					bdCand = holder.getBeanDefinition();
				}
				if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
					parse(bdCand.getBeanClassName(), holder.getBeanName());
				}
			}
		}
	}

	// Process any @Import annotations, 处理 @Import 注解
	processImports(configClass, sourceClass, getImports(sourceClass), true);

	// Process any @ImportResource annotations,处理 @ImportResource注解
	AnnotationAttributes importResource =
			AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
	if (importResource != null) {
		String[] resources = importResource.getStringArray("locations");
		Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
		for (String resource : resources) {
			String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
			configClass.addImportedResource(resolvedResource, readerClass);
		}
	}

	// Process individual @Bean methods,处理单个@Bean方法
	Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
	for (MethodMetadata methodMetadata : beanMethods) {
		configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
	}

	// Process default methods on interfaces
	processInterfaces(configClass, sourceClass);

	// Process superclass, if any  处理父类
	if (sourceClass.getMetadata().hasSuperClass()) {
		String superclass = sourceClass.getMetadata().getSuperClassName();
		if (superclass != null && !superclass.startsWith("java") &&
				!this.knownSuperclasses.containsKey(superclass)) {
			this.knownSuperclasses.put(superclass, configClass);
			// Superclass found, return its annotation metadata and recurse
			return sourceClass.getSuperClass();
		}
	}

	// No superclass -> processing is complete
	return null;
}

到此处,这一节下面都是讲处理 @ComponentScan注解!!

运行到下面断点处
在这里插入图片描述
进入ComponentScanAnnotationParser#parse()方法,进行一系列操作之后调用doScan()
在这里插入图片描述
进入ClassPathBeanDefinitionScanner#doScan()
在这里插入图片描述
进入ClassPathScanningCandidateComponentProvider#findCandidateComponents
在这里插入图片描述

进入ClassPathScanningCandidateComponentProvider#scanCandidateComponents
在这里插入图片描述
由于此时在com.liaoxiang包下只是给userDao加了@Repository注解,所以在这里被扫描到,途中变量的信息如下
在这里插入图片描述
最后返回bd集合candidates
在这里插入图片描述
回到ClassPathBeanDefinitionScanner#doScan()方法,进行其他一系列操作之后进入标识的方法中
在这里插入图片描述
调用本类中的方法,看到这些参数我们大概就能想到要干嘛了
在这里插入图片描述
进入BeanDefinitionReaderUtils#registerBeanDefinition()
在这里插入图片描述
看这个断点的条件就是我们上一节中调试的时候留下的,这是要向工厂中注册bd了!
在这里插入图片描述
果然进入到DefaultListableBeanFactory#registerBeanDefinition()
在这里插入图片描述
执行到这里UserDao就被加入到了beanDefinitionMap
在这里插入图片描述
执行完之后,返回ClassPathBeanDefinitionScanner#doScan()
在这里插入图片描述
回到ConfigurationClassParser#doProcessConfigurationClass()
在这里插入图片描述
执行完之后处理@Import注解,见下一节















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值