Spring5.1源码阅读记录二 - 一步步看bean是如何被创建起来的

一,准备工作

首先创建一个基础的环境,注意这几个放在一个包里面

1,启动环境

@Configuration
@ComponentScan(basePackages = "com.learn.day2")
@Import({Bean2.class})
@ImportResource
public class Day2Test {
	/**
	 * 查看Spring是如何注入的
	 * @param args
	 */
    public static void main(String[] args) {
                ApplicationContext context = new AnnotationConfigApplicationContext(Day2Test.class);
		Bean1 bean = context.getBean(Bean1.class);
		System.out.println(bean);

	}

}

2,带注解的Bean1

@Component
public class Bean1 {

}

3,不带注解的Bean2


public class Bean2 {

}

4,带注解的Bean3

@Component
public class Bean3 {
   @Autowired
   Bean2 bean2;
}

 二,开始调试

启动后首先进入到AnnotationConfigApplicationContext->this()初始化方法,这个先略过。。

	public AnnotationConfigApplicationContext(Class... annotatedClasses) {
		this();
		System.out.println("AnnotationConfigApplicationContext:调用this()方法");
		register(annotatedClasses);
		refresh();
	}

 

重点研究register()方法:最终调用 AnnotatedBeanDefinitionReader 的doRegisterBean()方法,此方法将配置类添加到BeanFactory的beanDefinitionMap中去

  • AnnotatedBeanDefinitionReader -> doRegisterBean()

//BeanDefinitionHolder 相当于一个map 通过name 获取BD


//如果是内部类 跳过
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
	return;
}


//设置BD属性
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);


//自定义BD属性
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
	customizer.customize(abd);
}

//相当于一个map 通过name 获取BD
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
  • BeanDefinitionReaderUtils -> registerBeanDefinition()

//注册所有的别名,并调用registerBeanDefinition 注册BD

// 使用baen名称注册
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

// 注册所有bean的别名
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
   for (String alias : aliases) {
      registry.registerAlias(beanName, alias);
   }
}
  • DefaultListableBeanFactory -> registerBeanDefinition()

这个方法判断当前容器是否有这个BD,如果有可覆盖就覆盖。

没有就判断当前容器初始化阶段,如果是创建阶段就直接直接放入BD

/** bean 定义的集合类 key是当前的beanName */
private final Map beanDefinitionMap = new ConcurrentHashMap<>(256);
//如果已经开始创建了 就直接加入
if (hasBeanCreationStarted()) {
	// Cannot modify startup-time collection elements anymore (for stable iteration)
	/**
	 * 全局的map 要加锁
	 */
	synchronized (this.beanDefinitionMap) {
		this.beanDefinitionMap.put(beanName, beanDefinition);
		List 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
	this.beanDefinitionMap.put(beanName, beanDefinition);
	this.beanDefinitionNames.add(beanName);
	removeManualSingletonName(beanName);
}

此时看下AnnotationConfigApplicationContext中BeanFactory已经创建起来了,并且BeanDefinitionMap中已经创建了一些BD,包含我们的配置类。

register()方法执行之前

Spring5.1源码阅读记录二 - 一步步看bean是如何被创建起来的_第1张图片

register()方法执行之后

Spring5.1源码阅读记录二 - 一步步看bean是如何被创建起来的_第2张图片

refresh()

再往下就是经典的refresh方法:让我们回到AnnotationConfigApplicationContext的refresh方法

  • prepareRefresh()

准备工作,记录下容器的启动时间、标记“已启动”状态、以及监听等

        protected void prepareRefresh() {
		// 将 active 属性设置为 true,closed 属性设置为 false,它们都是 AtomicBoolean 类型
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		this.active.set(true);
		// 实现初始化属性资源文件
		initPropertySources();
		// 校验 xml 配置文件
		getEnvironment().validateRequiredProperties();
		// 保存刷新容器之前的监听
		this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}
  • obtainFreshBeanFactory()

获取beanFactory 已经有了不是吗 略。。

prepareBeanFactory()加载classloader addBeanPostProcessor等 略。。

postProcessBeanFactory()略。。

invokeBeanFactoryPostProcessors()解析包 bean的操作在这里

一直往下面追踪到

AbstractApplicationContext -> invokeBeanFactoryPostProcessors ()

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

PostProcessorRegistrationDelegate -> invokeBeanFactoryPostProcessors()

sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);

invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();

PostProcessorRegistrationDelegate -> invokeBeanDefinitionRegistryPostProcessors()

for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
   postProcessor.postProcessBeanDefinitionRegistry(registry);
}

ConfigurationClassPostProcessor -> postProcessBeanDefinitionRegistry()

processConfigBeanDefinitions(registry);

ConfigurationClassPostProcessor -> processConfigBeanDefinitions()

//到这一步才是真正开始去扫描bean的操作,此时注册器,资源读取器等已经准备好
ConfigurationClassParser parser = new ConfigurationClassParser(
      this.metadataReaderFactory, this.problemReporter, this.environment,
      this.resourceLoader, this.componentScanBeanNameGenerator, registry);

Set candidates = new LinkedHashSet<>(configCandidates);
Set alreadyParsed = new HashSet<>(configCandidates.size());
do {
   //开始解析
   parser.parse(candidates);
   parser.validate();

 

ConfigurationClassParser -> parse()

try {
   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());
   }
}

ConfigurationClassParser ->processConfigurationClass()

SourceClass sourceClass = asSourceClass(configClass);
do {
   sourceClass = doProcessConfigurationClass(configClass, sourceClass);
}

ConfigurationClassParser->doProcessConfigurationClass()

Set 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());
   }
}

ComponentScanAnnotationParser -> parse()

//添加解析器 过滤条件等

ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
      componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);

Class generatorClass = componentScan.getClass("nameGenerator");
boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
      BeanUtils.instantiateClass(generatorClass));
return scanner.doScan(StringUtils.toStringArray(basePackages));

ClassPathBeanDefinitionScanner -> doScan()

Set beanDefinitions = new LinkedHashSet<>();
for (String basePackage : basePackages) {
   Set candidates = findCandidateComponents(basePackage);
   for (BeanDefinition candidate : candidates) {
      ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
      candidate.setScope(scopeMetadata.getScopeName());
      String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
      if (candidate instanceof AbstractBeanDefinition) {
         postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
      }
      if (candidate instanceof AnnotatedBeanDefinition) {
         AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
      }
      if (checkCandidate(beanName, candidate)) {
         BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
         definitionHolder =
               AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
         beanDefinitions.add(definitionHolder);
         registerBeanDefinition(definitionHolder, this.registry);
      }
   }
}

ClassPathScanningCandidateComponentProvider -> scanCandidateComponents()

Set candidates = new LinkedHashSet<>();
try {
   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);
            if (isCandidateComponent(metadataReader)) {
               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);
               }
.....

  

      }
   }
}

返回扫描到的了我们的三个Bean,并返回处理

Spring5.1源码阅读记录二 - 一步步看bean是如何被创建起来的_第3张图片

接下来回到doScan()返回BD集合

ClassPathBeanDefinitionScanner -> doScan()

if (checkCandidate(beanName, candidate)) {
   BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
   definitionHolder =
         AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
   beanDefinitions.add(definitionHolder);
   registerBeanDefinition(definitionHolder, this.registry);
}

BeanDefinitionReaderUtils->registerBeanDefinition()

这个方法是不是很熟悉?这个就是注册注解类的方法,讲BD添加到beanDefinitionMap中去

// 使用baen名称注册
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

// 注册所有bean的别名
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
   for (String alias : aliases) {
      registry.registerAlias(beanName, alias);
   }
}

好的,到这里我们的三个Bean,一个配置Bean都已经注册完了

Spring5.1源码阅读记录二 - 一步步看bean是如何被创建起来的_第4张图片

接下来再回到doScan()方法,抛一个引子后面会说到

// 处理@Import注解 注册制定的类 springboot很重要的注解
processImports(configClass, sourceClass, getImports(sourceClass), true);

// 处理@ImportResource 注解 注册资源文件 还记得Mybatise吗
AnnotationAttributes importResource =
      AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
   String[] resources = importResource.getStringArray("locations");
   Class readerClass = importResource.getClass("reader");
   for (String resource : resources) {
      String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
      configClass.addImportedResource(resolvedResource, readerClass);
   }
}

现在整个项目中的可用BD都已经拿到了,然后我们继续经典的Refresh()方法

AnnotationConfigApplicationContext -> refresh()

registerBeanPostProcessors(beanFactory);  //添加几个处理器..

initMessageSource();  //国际化

initApplicationEventMulticaster();//初始化当前 ApplicationContext 的事件广播器

onRefresh();//初始化一些特殊的Bean,有需求就实现它

registerListeners();//注册监听器

finishBeanFactoryInitialization(beanFactory);//初始化所有单例Bean

DefaultListableBeanFactory->preInstantiateSingletons()

if (isFactoryBean(beanName)) {
   Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
   if (bean instanceof FactoryBean) {
   ....
   }
}
else {
   getBean(beanName);
}

AbstractBeanFactory->doGetBean(String name)

这个方法主要做了两件事。第一件事是在创建Bean前给InstantiationAwareBeanPostProcess机会处理创建Bean返回;第二件事是调用doCreateBean创建Bean。 

try {
   // 初始化之前的通知 可以返回一个代理Bean
   Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
   if (bean != null) {
      return bean;
   }
}
catch (Throwable ex) {
   throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
         "BeanPostProcessor before instantiation of bean failed", ex);
}
try {
   //开始创建实例对象
   Object beanInstance = doCreateBean(beanName, mbdToUse, args);
   if (logger.isTraceEnabled()) {
      logger.trace("Finished creating instance of bean '" + beanName + "'");
   }
   return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
   // A previously detected exception with proper bean creation context already,
   // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
   throw ex;
}

AbstractAutowireCapableBeanFactory -> doCreateBean()

调用Bean的构造函数创建Bean,这时候并没有初始化Bean; 

    		// 实例化Bean the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			//调用Bean的构造函数创建Bean,这时候并没有初始化Bean;
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}

实例化Bean的所有字段  

                // 就是实例化Bean的字段
		Object exposedObject = bean;
		try {
			//其中populateBean中会自动注入带有@Autowired,@Resource等注解的Bean
			populateBean(beanName, mbd, instanceWrapper);
			exposedObject = initializeBean(beanName, exposedObject, mbd);//实例化Bean
		}
		catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}
			else {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}

AbstractAutowireCapableBeanFactory->initializeBean()

	protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}

		//前置通知其
		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}
		
		//init方法
		try {
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		//后置通知其
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	} 
  

至此,一个Bean对象就创建完成了

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Spring随笔,SpringMVC)