1.准备测试类
public class Test01 {
public static void main(String[] args) {
//这个构造方法会把Spring所有的环境都准备好
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
}
}
配置类
@ComponentScan("com.v1")
@Component
@Configuration
public class SpringConfiguration {
}
PersonService类
@Component
public class PersonService {
}
2.点击`AnnotationConfigApplicationContext`
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//这个类有父类,所以会先初始化父类的构造方法,接着初始化自己的构造方法
//调用无参构造方法进行初始化一个读取器和扫描仪
this();
//把配置类加载进 DefaultListableBeanFactory 的map集合中
//配置类可以一次性传多个,这个方法执行后,只是把配置类加载进了 DefaultListAbleBeanFactory的map集合中
//还没有扫描其他的的加了组件的类
register(annotatedClasses);
//实例化所有被加了组件的对象
refresh();
}
3.点击`refresh()`
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//调用容器准备刷新的方法,获取容器的当时时间,同时给容器设置同步标识
//这个方法不是重点,可以暂时认为他不干任何事情
prepareRefresh();
//获取工厂对象 ,本质是DefaultListableBeanFactory对象
//其实读取xml文件变成beanDefinition,也是在这里面完成的
//所以这里面的功能和register(annotatedClasses);功能很像
//一个是是从xml文件中读取配置信息,一个是通过类的注解读取信息
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//为BeanFactory配置类加载器、后置处理器等等
//这个方法比较重要
prepareBeanFactory(beanFactory);
try {
//这个方法是空方法,Spring还没有做任何事情
//猜测以后Spring会使用这个方法
postProcessBeanFactory(beanFactory);
//在这个方法中开始扫描被组件标记的类, 把类的信息
// 封装成一个GenericBeanDefinition存储在map集合中
//这个是非常重要的一个方法
invokeBeanFactoryPostProcessors(beanFactory);
//省略剩余代码...
}
4.点击 `invokeBeanFactoryPostProcessors(beanFactory)`
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//重点方法,执行beanFactoryPostProcessors后置处理器
//注意这里 getBeanFactoryPostProcessors() 是获取不到用户自己的BeanFactoryPostProcessor的实现类的 ,因为这个时候还没有开始扫描包
//需要自己手动赋值给这个大容器对象,也就是AnnotationConfigApplicationContext
//ac.addBeanFactoryPostProcessor(....);
//getBeanFactoryPostProcessors()可以获取到用户自定义的作用类,前提是手动创建,传进来的
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
5.点击 `invokeBeanFactoryPostProcessors`
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// 1. 处理用户自己的后置处理器,处理的是用户自己创建对象传的ac.addBeanFactoryPostProcessor()
//如果你想在扫描所有包之前就执行你的后置处理器的话,可以首先把的后置处理器注册给Spring
//就是通过 ac.addBeanFactoryPostProcessor(对象) 这样子注解
Set<String> processedBeans = new HashSet<>();
//判断当前的beanFactory是否是BeanDefinitionRegistry
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//定义两个集合BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor
//bdrpp 增强了一个功能 ,也就是说他们的功能是不一样的,所以需要定义两个集合
//regularPostProcessors 存储用户自己传进来的BeanFactoryPostProcessor的实现类
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
//registryProcessors存储用户自己传进来的BeanDefinitionRegistryPostProcessor的实现类
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
//判断的bean是否实现了BeanDefinitionRegistryPostProcessor
//如果bean实现了BeanDefinitionRegistryPostProcessor这个接口,可以获取到整个容器对象,也就是registry对象
//而实现BeanFactoryPostProcessor,只能获取 到bean工厂 对象
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
//如果当前的bean实现的是BeanDefinitionRegistryPostProcessor
//添加进registryProcessors集合
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
//如果只是实现了beanFactoryPostProcessors添加进regularPostProcessors集合
regularPostProcessors.add(postProcessor);
}
}
//其实前面都不是重点,基本不会有人自己手动创建对象添加给Spring容器的,以下才是重点
//2.处理Spring内部的后置处理器,Spring内部的处理器 ,就只有一个类实现BeanDefinitionRegistryPostProcessor
//currentRegistryProcessors存放Spring内部类实现了BeanDefinitionRegistryPostProcessor接口的类
//ConfigurationClassPostProcessor 这个就是实现类 BeanDefinitionRegistryPostProcessor
//ConfigurationClassPostProcessor就是Spring内部的后置处理器
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
//从beanFactory工厂中寻找判断哪个类型实现了BeanDefinitionRegistryPostProcessor接口,拿出该类的beanName
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
//遍历所有的后置处理器beanName ,通过beanName从bean工厂中把对象取出来
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//把名称存储到processedBeans集合中
processedBeans.add(ppName);
}
}
//排序,不是重点 ,内部只有一个
sortPostProcessors(currentRegistryProcessors, beanFactory);
//合并list ,把用户之间定义和Spring之间内部的合并在一个集合中
//合并基本是没有用的,一般用户不会自己手动创建对象注册进Spring容器
registryProcessors.addAll(currentRegistryProcessors);
//执行当前的后置处理器,其实到这里currentRegistryProcessors只有一个处理器,
//主要处理扫描配置类对应包下的类
//点击这个
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//清空集合
currentRegistryProcessors.clear();
//剩余代码省略....其实下面的代码也有一部分很重要的,以后再聊
}
6.点击 `invokeBeanDefinitionRegistryPostProcessors`方法
该方法把 currentRegistryProcessors
集合和全局对象registry
传入
currentRegistryProcessors
其实该集合仅仅是存储到了一个类 ConfigurationClassPostProcessor
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
//遍历集合,其实只有一个类,而这个类正是ConfigurationClassPostProcessor
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
//开始执行 ConfigurationClassPostProcessor 的方法
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
7.点击`postProcessBeanDefinitionRegistry`
该方法其实是 BeanDefinitionRegistryPostProcessor
接口继承了 BeanFactoryPostProcessor
扩展的方法
@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);
}
8.点击 `processConfigBeanDefinitions`
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
//所有被加了注解的bean,都将存储在configCandidates这个集合中
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
//获取工厂中所有的beanName
String[] candidateNames = registry.getBeanDefinitionNames();
//遍历所有的beanName
for (String beanName : candidateNames) {
//通过beanName获取到对象
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
//判断该对象时候被处理过了,ConfigurationClass属性为full或者是lite,则意味着已经处理过了
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
//循环中判断当前的对象是否用@Component,@ComponentScan等类型的注解
//如果当前的bean(其实就是配置类)有带@configuration 则属性值添加为 full
//如果当前的bean没有带 @Configuration 则属性添加为 lite
//checkConfigurationClassCandidate()判断是否是加了注解的类
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
//存储在configCandidates集合中
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// Return immediately if no @Configuration classes were found
if (configCandidates.isEmpty()) {
return;
}
// Sort by previously determined @Order value, if applicable
//如果有bean加了@Order注解的,进行排序,没有的默认排序,不是重点
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
//不是重点
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
//实例化ConfigurationClassParser,为了解析各个配置类
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
//有创建两个集合,去掉重复的配置类
//因为有可能有重复的配置类,Spring内部提供的话是不可能有重复的,但是你提供的话就有可能重复的,你可以一次性提供多个同样的配置类进入
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
//扫描包,其实还有 其他功能的,这是Spring非常核心的功能
//此时的candidates中其实就只有一个配置类 parse根据配置类开始扫描带有注解的类
//点击这个方法
parser.parse(candidates);
parser.validate();
//把读取出来的类实现了 ImportSelector 返回的类集合赋值给 configClasses集合
//parser.getConfigurationClasses() 把我们解析器存储好的类拿出来了,准备把 实现了 ImportSelector接口返回的类注册到map中
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
//在这里把@Import里面的返回的类,放到bean工厂的map集合中
//configClasses集合添加到bean工厂的map集合中
//@Import中填写的类有三种形式
//1.ImportSelector 2.ImportBeanDefinitionRegistrar 3.普通类
//通俗地来说如果每个类使用了 @Import导入某个类
//1.实现了ImportSelector的类 ,把重写方法返回的全类名生成的beanDefinition存储在了configClasses集合中
//2.实现了ImportBeanDefinitionRegistrar接口的类,里面的beanDefinition也被放到configClasses集合中
//3.普通的类也是一样
//其实configClasses存储所有的beanDefinition,在这个方法里面还会进行判断
//看哪个beanDefinition是实现了mportSelector,哪个类里面是有@Bean的
//哪个是 实现ImportBeanDefinitionRegistrar的
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
candidates.clear();
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<>();
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
for (String candidateName : newCandidateNames) {
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
while (!candidates.isEmpty());
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
// Clear cache in externally provided MetadataReaderFactory; this is a no-op
// for a shared cache since it'll be cleared by the ApplicationContext.
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
9.点击 `parser.parse(candidates);`
candidates
为用户所有配置类的集合
public void parse(Set<BeanDefinitionHolder> configCandidates) {
//遍历每个beanHolder,其实这个bean中都是被加了注解的
//其实一般就是配置类configCandidates只有一个
for (BeanDefinitionHolder holder : configCandidates) {
//获取每个beanDefinition
BeanDefinition bd = holder.getBeanDefinition();
try {
//判断当前的bean时候是被加注解的,其实是肯定被加了注解的,前面已经做过判断了
if (bd instanceof AnnotatedBeanDefinition) {
//解析 把配置类的元数据对象 和 beanName传过去
//点击这个方法
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
//不是被加注解的,Spring内部的类
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);
}
}
this.deferredImportSelectorHandler.process();
}
10.点击`parse`方法
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
//创建了ConfigurationClass对象,也可以理解为一个临时的容器方便传参数
//ConfigurationClass作为一个数据结构,重新把元数据和beanName存储起来
processConfigurationClass(new ConfigurationClass(metadata, beanName));
}
11.点击processConfigurationClass
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
//是否要跳过解析,不是重点
//这里的configClass就是元数据对象和beanName的数据结构
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
//处理Imported情况
//当前的类有没有被其他的类导入
ConfigurationClass existingClass = this.configurationClasses.get(configClass);
if (existingClass != null) {
if (configClass.isImported()) {
if (existingClass.isImported()) {
existingClass.mergeImportedBy(configClass);
}
// Otherwise ignore new imported config class; existing non-imported class overrides it.
return;
}
else {
// Explicit bean definition found, probably replacing an import.
// Let's remove the old one and go with the new one.
this.configurationClasses.remove(configClass);
this.knownSuperclasses.values().removeIf(configClass::equals);
}
}
// Recursively process the configuration class and its superclass hierarchy.
//把configClass获取SourceClass对象,有封装了一个对象
SourceClass sourceClass = asSourceClass(configClass);
do {
//点击这个方法
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
}
while (sourceClass != null);
//扫描出来的所有的beanDefinition
//多个递归调用之后,这个集合会存储着 所有的配置类,所有被加了注解的类,以及实现了 ImportSelector 接口返回的类
this.configurationClasses.put(configClass, configClass);
}
11.点击 doProcessConfigurationClass
@Nullable
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
throws IOException {
//判断当前的类是否有@Component注解
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// 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.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
// Process any @ComponentScan annotations
//处理 @ComponentScan 注解
//一个类可以写多个@ComponentScan 注解 ,所以获取当前这个类所有@ComponentScan 注解
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
//这个方法就是把componentScans下所有的包扫描了,并且把beanDefinition存储在beanFactory中了
//返回的就是当前包下所有的beanDefinition
//sourceClass.getMetadata().getClassName() 当前类的全类名
//componentScan 当前类的注解对象
//scannedBeanDefinitions 返回的集合存储了被扫描出来的beanDefinition
Set<BeanDefinitionHolder> scannedBeanDefinitions =
//点击这个
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
//scannedBeanDefinitions集合里面的所有bean已经被存储在beanFactory的map集合中了
//现在再次遍历所有的bean,查看这些beanDefinition中时候也存在 @ComponetScan @Import 等等注解
//如果有的话,也会进行注册到map集合中, 好精妙 太厉害了,厉害
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
//重新开始执行这个过程,查看被放进map的bean有没有@ComponetScan,@Import等注解
//递归判断
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// Process any @Import annotations
//到这一步时所有带@Component等注解的类都被加进Spring的BeanDefinitionMap集合中了
//处理 @Import 注解 @Import其实可以写三种类型的在里面
//1. ImportSelector这个类 2.ImportBeanDefinitionRegistrar 3,普通的类
// getImports(sourceClass) 其实是直接判断当前类是否有@Import注解 ,有的话拿出里面的类
processImports(configClass, sourceClass, getImports(sourceClass), true);
//省略剩余代码.....
}
12.点击 `this.componentScanParser.parse`
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
//主要用来生成beanName的beanName生成器
Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
BeanUtils.instantiateClass(generatorClass));
//web当中在学
ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
scanner.setScopedProxyMode(scopedProxyMode);
}
else {
Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
}
scanner.setResourcePattern(componentScan.getString("resourcePattern"));
//扫描特定的类
for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addIncludeFilter(typeFilter);
}
}
//排除某些特定的类
for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addExcludeFilter(typeFilter);
}
}
//当前这个配置类 是否需要懒加载,其他类还没有扫描出来
boolean lazyInit = componentScan.getBoolean("lazyInit");
if (lazyInit) {
scanner.getBeanDefinitionDefaults().setLazyInit(true);
}
Set<String> basePackages = new LinkedHashSet<>();
String[] basePackagesArray = componentScan.getStringArray("basePackages");
for (String pkg : basePackagesArray) {
String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
Collections.addAll(basePackages, tokenized);
}
for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
basePackages.add(ClassUtils.getPackageName(clazz));
}
if (basePackages.isEmpty()) {
basePackages.add(ClassUtils.getPackageName(declaringClass));
}
scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
@Override
protected boolean matchClassName(String className) {
return declaringClass.equals(className);
}
});
//真正其作用的扫描
return scanner.doScan(StringUtils.toStringArray(basePackages));
}
13.点击 `scanner.doScan`
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
//可能是多个参数的
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
//遍历包
for (String basePackage : basePackages) {
//扫描basePackage包下的java文件并把文件转换为BeanDefinition
//这里面使用呢的asm扫描 Class文件
//点击这个方法
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
//当前的BeanDefinition是单例的,还是多例的
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
//现在这里的bean被扫描出来了
//如果这个类是AbstractBeanDefinition子类 进来
//设置一些默认lazy init属性
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
//虽然上面由给了默认值,但是我们用户也是可以修改默认值的
//这里就判断该bean是否添加了lazy,Primary,DependsOn Role等注解
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
//这个是重点, 在这里终于把 扫描beanDefinition添加进bean工厂中
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
14.点击 `findCandidateComponents`
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
}
else {
//这里扫描
return scanCandidateComponents(basePackage);
}
}
15.点击 `scanCandidateComponents`
在这个方法中,Spring使用了 asm技术读取@ComponentScan
包下所有的类,
判断该类有没有写 @Component
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
//加了注解资源被暂时存储在这里
Set<BeanDefinition> candidates = new LinkedHashSet<>();
try {
//使用的是asm读取class文件
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + '/' + this.resourcePattern;
Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
boolean traceEnabled = logger.isTraceEnabled();
boolean debugEnabled = logger.isDebugEnabled();
for (Resource resource : resources) {
if (traceEnabled) {
logger.trace("Scanning " + resource);
}
if (resource.isReadable()) {
try {
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
//判断当前的class文件是否加注解
if (isCandidateComponent(metadataReader)) {
//sbd元数据对象 ScannedGenericBeanDefinition 继承 GenericBeanDefinition 继承 AbstractBeanDefinition
//给加了注解的类创建描述类
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setResource(resource);
sbd.setSource(resource);
if (isCandidateComponent(sbd)) {
if (debugEnabled) {
logger.debug("Identified candidate component class: " + resource);
}
candidates.add(sbd);
}
else {
if (debugEnabled) {
logger.debug("Ignored because not a concrete top-level class: " + resource);
}
}
}
else {
if (traceEnabled) {
logger.trace("Ignored because not matching any filter: " + resource);
}
}
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to read candidate component class: " + resource, ex);
}
}
else {
if (traceEnabled) {
logger.trace("Ignored because not readable: " + resource);
}
}
}
}
catch (IOException ex) {
throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
}
//返回集合
return candidates;
}
16.回到 `doScan`中
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
//可能是多个参数的
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
//遍历包
for (String basePackage : basePackages) {
//扫描basePackage包下的java文件并把文件转换为BeanDefinition
//这里面使用呢的asm扫描 Class文件
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
//当前的BeanDefinition是单例的,还是多例的
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
//现在这里的bean被扫描出来了
//如果这个类是AbstractBeanDefinition子类 进来
//设置一些默认lazy init属性
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
//虽然上面由给了默认值,但是我们用户也是可以修改默认值的
//这里就判断该bean是否添加了lazy,Primary,DependsOn Role等注解
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
//这个是重点, 在这里终于把 扫描beanDefinition添加进bean工厂中
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
17.点击 `registerBeanDefinition`
protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) {
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
}
18.点击 `registerBeanDefinition`
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
//获取beanName的名称
String beanName = definitionHolder.getBeanName();
//现在把definitionHolder拆分了,又把 AnnotatedGenericBeanDefinition拿出来了
//似乎definitionHolder就只是封装了一下,然后又给拆分, 可以理解为一个临时的容器
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
//这个不重要,spring当中处理别名的
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
19.Ctrl+Alt+B 点击 `registry.registerBeanDefinition`
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isInfoEnabled()) {
logger.info("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
}
else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
//这个地方把Spring扫描用户定义的bean存储到map集合中
this.beanDefinitionMap.put(beanName, beanDefinition);
//每添加一个对象进 map集合中 beanDefinitionNames 长度加1
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
removeManualSingletonName(beanName);
}
}
else {
// Still in startup registration phase
//在这个方法中就把 beanDefinition 存储在 DefaultListableBeanFactory的map集合中
//顾名思义,beanDefinitionMap就是一个存储beanDefinition的map集合
//在这个集合当中还有Spring当中本身已经初始好的对象
this.beanDefinitionMap.put(beanName, beanDefinition);
//把beanName存储在这个list集合中
this.beanDefinitionNames.add(beanName);
//这个是去重的,不是重点
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
最后把扫描出来的组件封装成 BeanDefinition
添加到map集合中
呀呀好复杂啊,你要是仔细看完了,你就是这条街最亮的仔
Spring5源码地址:
github.com/zouchangfu/… gitee.com/zouchangfu/…
Spring5源码都是已经构建好的了,无需再使用gradle进行构建了,直接打开就可以跑起来