了解Spirng 的启动过程,可以知晓Spring 中对于BeanDefinition 的生成和不同类型bean 的创建工作,了解bean 的前置后置处理器,可以在定义bean 的时候知晓其工作的原理。
spring 启动过程实际上就是bean 的创建过程,当spring启动完成,可以在业务层面直接使用各种各样的bean,创建bean工厂,然后解析配置类,配置默认的一些单例bean ,创建非懒加载的单例bean ,发布容器创建完成事件;
Spring 的启动过程包括:
加载配置文件:Spring启动时首先会读取配置文件,通常是通过ApplicationContext来加载配置文件。配置文件可以是XML格式的,也可以是注解方式的配置类,包含了Spring容器所需的配置信息。
创建并初始化IOC容器:Spring根据加载的配置文件创建IOC(Inversion of Control,控制反转)容器。IOC容器负责管理和组织Bean的实例化过程,可以根据配置信息创建和管理Bean对象。
扫描和注册Bean:IOC容器会扫描配置文件中指定的包路径,根据配置规则扫描并注册Bean。对于XML配置方式,需要在配置文件中明确指定要扫描的包路径。对于注解配置方式,可以使用@ComponentScan注解来指定要扫描的包路径。
解析依赖关系:在注册Bean的过程中,Spring会解析Bean之间的依赖关系。通过依赖注入的方式,将依赖的Bean注入到相应的Bean中,满足Bean之间的依赖关系。
触发生命周期回调:在IOC容器初始化完成后,Spring会触发Bean的生命周期回调方法。生命周期回调方法包括初始化方法和销毁方法。初始化方法在Bean创建完成后执行,可用于完成一些初始化设置。销毁方法在Bean不再使用时执行,可用于释放资源等操作。
完成启动过程:一旦以上步骤都完成,Spring框架就启动完成了。此时,应用程序就可以使用Spring容器中的Bean进行开发和调用。
pring的启动过程包括加载配置文件、创建IOC容器、注册Bean、解析依赖关系、触发生命周期回调等步骤。通过这些步骤,Spring实现了IOC和DI的机制,提供了便捷的Bean管理和依赖注入功能。
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(xxxx.class);
AnnotationConfigApplicationContext 构造方法:
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
// 构造方法调用
this();
// 将 componentClasses 包装成BeanDefinition 放入到BeanDefinition map 中
this.register(componentClasses);
// 扫描生成bean 定义,生成bean ,发布事件等
this.refresh();
}
this(); 调用构造方法
// 调用父类的构造方法 GenericApplicationContext 对 DefaultListableBeanFactory beanFactory 实例化
// 向beanFactory 设置各种各样的注解解析器
public AnnotationConfigApplicationContext() {
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
// bean reader 实例化 设置各种各样的注解解析器
this.reader = new AnnotatedBeanDefinitionReader(this);
createAnnotatedBeanDefReader.end();
// bean 扫描 实例化 默认 扫描加了某些注解的类
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
refresh 方法 刷新生成BeanDefinition,生成 非懒加载的单例bean
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 资源准备获取额外的资源
this.prepareRefresh();
// 获取bean 工厂
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
// 设置 bean 工厂 ClassLoader ,设置spring 的表达式解析,设置默认的类型转换器
// 设置aware 接口回调
// 设置一些默认类型的bean 单例对象
this.prepareBeanFactory(beanFactory);
try {
// bean 工厂的后置处理器
this.postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 扫描注册bean 定义到 beanFactory 中
this.invokeBeanFactoryPostProcessors(beanFactory);
// BeanFactory中所有的BeanPostProcessor找出来并实例化得到一个对象,
// 这个list 集合中实现了顺序为实现了 PriorityOrdered在最前面
// 其次是实现了Ordered 接口的,最后是两个都没有实现的 BeanPostProcessor
// 特殊情况如果它实现了MergedBeanDefinitionPostProcessor 接口则放到最后
// 并添加到BeanFactory中去(属性beanPostProcessors)
this.registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// 设置国际化的一些资源
this.initMessageSource();
// 设置事件广播器
this.initApplicationEventMulticaster();
this.onRefresh();
// 注册监听器,发布事件后,可以进行事件的监听
this.registerListeners();
// 非懒加载的单例bean 生成
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var10) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var10);
}
this.destroyBeans();
this.cancelRefresh(var10);
throw var10;
} finally {
this.resetCommonCaches();
contextRefresh.end();
}
}
}
invokeBeanFactoryPostProcessors 扫描生成bean 定义:通过beanFactory 的后置处理器去扫描生成bean 定义
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 调用 beanFactory 的后置处理器
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());
if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
invokeBeanFactoryPostProcessors 调用:
beanFactory bean 工厂;beanFactoryPostProcessors 通过ApplicationContext register 方法注册进来的beanFactoryPostProcessors 集合,如果没有进行手动注册,改集合为空。先执行postProcessBeanDefinitionRegistry 完成bean 定义的注册;
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
Set<String> processedBeans = new HashSet();
ArrayList regularPostProcessors;
ArrayList registryProcessors;
int var9;
ArrayList currentRegistryProcessors;
String[] postProcessorNames;
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;
regularPostProcessors = new ArrayList();
registryProcessors = new ArrayList();
Iterator var6 = beanFactoryPostProcessors.iterator();
// 一般情况下 beanFactoryPostProcessors 我们没有进行手动注入,改集合是空的
while(var6.hasNext()) {
BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var6.next();
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;
// 执行通过ApplicationContext添加进来的BeanDefinitionRegistryPostProcessor
// 的postProcessBeanDefinitionRegistry()方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
} else {
// 添加普通的 直接实现 BeanFactoryPostProcessor 接口的类
regularPostProcessors.add(postProcessor);
}
}
currentRegistryProcessors = new ArrayList();
// 从 beanFactory 拿到 BeanDefinitionRegistryPostProcessor 类型的 bean 定义
// 可以拿到ConfigurationClassPostProcessor 他在准备工作时就已经放入了
// 它也是一个BeanDefinitionRegistryPostProcessor 并且也是 PriorityOrdered
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
String[] var16 = postProcessorNames;
var9 = postProcessorNames.length;
int var10;
String ppName;
for(var10 = 0; var10 < var9; ++var10) {
ppName = var16[var10];
// 是否实现PriorityOrdered
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 实现PriorityOrdered 通过getBean 获取对象
// 这里生成了 ConfigurationClassPostProcessor 的bean 对象
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// 记录已经执行过的bean
processedBeans.add(ppName);
}
}
// 升序排序 按照实现了getOrder() 放回的值进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//
registryProcessors.addAll(currentRegistryProcessors);
// 执行BeanFactory中实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor
// 的postProcessBeanDefinitionRegistry()方法
// 这里会调用 ConfigurationClassPostProcessor 中的 postProcessBeanDefinitionRegistry 方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
// 获取 BeanDefinitionRegistryPostProcessor 类型的bean 定义
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
var16 = postProcessorNames;
var9 = postProcessorNames.length;
for(var10 = 0; var10 < var9; ++var10) {
ppName = var16[var10];
// 过滤已经处理过的bean
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
// 这个bean 实现了 Ordered 接口的类,通过bean 获取对象
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// 记录已经执行过的bean
processedBeans.add(ppName);
}
}
// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 执行BeanFactory中实现了Ordered接口的BeanDefinitionRegistryPostProcessor
// 的postProcessBeanDefinitionRegistry()方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
boolean reiterate = true;
while(reiterate) {
reiterate = false;
// 获取 BeanDefinitionRegistryPostProcessor 类型的bean 定义
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
String[] var19 = postProcessorNames;
var10 = postProcessorNames.length;
for(int var26 = 0; var26 < var10; ++var26) {
String ppName = var19[var26];
// 获取没有处理过的bean (没有实现PriorityOrdered 和 Ordered 接口的类)
if (!processedBeans.contains(ppName)) {
// 生成bean 对象
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 执行BeanFactory中其他的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
}
// 执行上面所有的BeanDefinitionRegistryPostProcessor的postProcessBeanFactory()方法
invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);
// 执行通过ApplicationContext添加进来的BeanFactoryPostProcessor的postProcessBeanFactory()方法
invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
} else {
// 执行注册BeanFactoryPostProcessor 但是没有实现 BeanDefinitionRegistry的
// postProcessBeanFactory()方法
invokeBeanFactoryPostProcessors((Collection)beanFactoryPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
}
// 获取类型为 BeanFactoryPostProcessor 的 bean 名称
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
regularPostProcessors = new ArrayList();
registryProcessors = new ArrayList();
currentRegistryProcessors = new ArrayList();
postProcessorNames = postProcessorNames;
int var20 = postProcessorNames.length;
String ppName;
for(var9 = 0; var9 < var20; ++var9) {
ppName = postProcessorNames[var9];
if (!processedBeans.contains(ppName)) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
regularPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
registryProcessors.add(ppName);
} else {
currentRegistryProcessors.add(ppName);
}
}
}
sortPostProcessors(regularPostProcessors, beanFactory);
// 执行BeanFactory中实现了PriorityOrdered接口的BeanFactoryPostProcessor
// 的postProcessBeanFactory()方法
invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList(registryProcessors.size());
Iterator var21 = registryProcessors.iterator();
while(var21.hasNext()) {
String postProcessorName = (String)var21.next();
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
// 执行BeanFactory中实现了Ordered接口的BeanFactoryPostProcessor的postProcessBeanFactory()方法
invokeBeanFactoryPostProcessors((Collection)orderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList(currentRegistryProcessors.size());
Iterator var24 = currentRegistryProcessors.iterator();
while(var24.hasNext()) {
ppName = (String)var24.next();
nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
// 执行BeanFactory中其他的BeanFactoryPostProcessor的postProcessBeanFactory()方法
invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
beanFactory.clearMetadataCache();
}
这里其实就是执行实现了 BeanDefinitionRegistryPostProcessor 接口的postProcessBeanDefinitionRegistry 和 postProcessBeanFactory 方法:先执行postProcessBeanDefinitionRegistry 在执行postProcessBeanFactory 方法
postProcessBeanDefinitionRegistry demo:
@Component
public class ConfigBean implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry)
throws BeansException {
// BeanDefinitionRegistryPostProcessor 的接口方法直接进行bean 的定义处理 ; 先执行
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory)
throws BeansException {
// BeanFactoryPostProcessor 的接口方法只能进行使用不能进行bean 定义的处理 ;后执行
}
}
ConfigurationClassPostProcessor 中的 postProcessBeanDefinitionRegistry 方法进行扫描生成bean定义:
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);
} else if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + registry);
} else {
this.registriesPostProcessed.add(registryId);
// 扫描注册bean 定义
this.processConfigBeanDefinitions(registry);
}
}
processConfigBeanDefinitions 扫描生成bean 定义:
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList();
// 获取所有的bean 定义
String[] candidateNames = registry.getBeanDefinitionNames();
String[] var4 = candidateNames;
int var5 = candidateNames.length;
for(int var6 = 0; var6 < var5; ++var6) {
String beanName = var4[var6];
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
//
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
} else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
// 如果是配置类 则将配置保证成 BeanDefinitionHolder 放入到集合中
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// 解析配置类
if (!configCandidates.isEmpty()) {
// 先进行 升序排序
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("org.springframework.context.annotation.internalConfigurationBeanNameGenerator");
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
// 获取各种解析器
ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet(configCandidates.size());
do {
StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
// 通过解析器解析配置类
parser.parse(candidates);
parser.validate();
// 获取已经解析的配置类
Set<ConfigurationClass> configClasses = new LinkedHashSet(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry());
}
// 真正去对配置类生成 bean 定义
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
processConfig.tag("classCount", () -> {
return String.valueOf(configClasses.size());
}).end();
candidates.clear();
// 如果解析配置类后发现有新加入的配置类,则继续下一次循环 解析下一批的配置类
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet();
Iterator var13 = alreadyParsed.iterator();
while(var13.hasNext()) {
ConfigurationClass configurationClass = (ConfigurationClass)var13.next();
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
String[] var24 = newCandidateNames;
int var25 = newCandidateNames.length;
for(int var15 = 0; var15 < var25; ++var15) {
String candidateName = var24[var15];
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());
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
((CachingMetadataReaderFactory)this.metadataReaderFactory).clearCache();
}
}
}
ConfigurationClassUtils # checkConfigurationClassCandidate
public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
String className = beanDef.getBeanClassName();
if (className != null && beanDef.getFactoryMethodName() == null) {
AnnotationMetadata metadata;
if (beanDef instanceof AnnotatedBeanDefinition && className.equals(((AnnotatedBeanDefinition)beanDef).getMetadata().getClassName())) {
metadata = ((AnnotatedBeanDefinition)beanDef).getMetadata();
} else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition)beanDef).hasBeanClass()) {
Class<?> beanClass = ((AbstractBeanDefinition)beanDef).getBeanClass();
if (BeanFactoryPostProcessor.class.isAssignableFrom(beanClass) || BeanPostProcessor.class.isAssignableFrom(beanClass) || AopInfrastructureBean.class.isAssignableFrom(beanClass) || EventListenerFactory.class.isAssignableFrom(beanClass)) {
return false;
}
metadata = AnnotationMetadata.introspect(beanClass);
} else {
try {
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
metadata = metadataReader.getAnnotationMetadata();
} catch (IOException var6) {
if (logger.isDebugEnabled()) {
logger.debug("Could not find class file for introspecting configuration annotations: " + className, var6);
}
return false;
}
}
// 从原数据 获取 Configuration 注解
Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
// 如果 有注解 并且proxyBeanMethods 属性值是true
// 则标识改配置为 full 配置类
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, "full");
} else {
// 如果没有 Configuration 或者 proxyBeanMethods 是 false
// 或者 他也没有 Component /ComponentScan/Import/ImportResource
// 或者它是一个接口
// 或者类里面 也没有定义@Bean的方法
// 则直接返回 false
if (config == null && !isConfigurationCandidate(metadata)) {
return false;
}
// 不是接口,并且是 Component /ComponentScan/Import/ImportResource 中一个 或者类中有@Bean 的方法
// 则标识改配置为 lite 配置类
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, "lite");
}
Integer order = getOrder(metadata);
if (order != null) {
beanDef.setAttribute(ORDER_ATTRIBUTE, order);
}
return true;
} else {
return false;
}
}
isConfigurationCandidate 判断是否配置类:
public static boolean isConfigurationCandidate(AnnotationMetadata metadata) {
if (metadata.isInterface()) {
return false;
} else {
Iterator var1 = candidateIndicators.iterator();
String indicator;
do {
if (!var1.hasNext()) {
return hasBeanMethods(metadata);
}
indicator = (String)var1.next();
} while(!metadata.isAnnotated(indicator));
return true;
}
}
parser.parse(candidates) 解析配置类:
public void parse(Set<BeanDefinitionHolder> configCandidates) {
Iterator var2 = configCandidates.iterator();
while(var2.hasNext()) {
BeanDefinitionHolder holder = (BeanDefinitionHolder)var2.next();
BeanDefinition bd = holder.getBeanDefinition();
try {
if (bd instanceof AnnotatedBeanDefinition) {
this.parse(((AnnotatedBeanDefinition)bd).getMetadata(), holder.getBeanName());
} else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition)bd).hasBeanClass()) {
this.parse(((AbstractBeanDefinition)bd).getBeanClass(), holder.getBeanName());
} else {
this.parse(bd.getBeanClassName(), holder.getBeanName());
}
} catch (BeanDefinitionStoreException var6) {
throw var6;
} catch (Throwable var7) {
throw new BeanDefinitionStoreException("Failed to parse configuration class [" + bd.getBeanClassName() + "]", var7);
}
}
this.deferredImportSelectorHandler.process();
}
protected final void parse(@Nullable String className, String beanName) throws IOException {
Assert.notNull(className, "No bean class name for configuration class bean definition");
MetadataReader reader = this.metadataReaderFactory.getMetadataReader(className);
// 解析配置类
this.processConfigurationClass(new ConfigurationClass(reader, beanName), DEFAULT_EXCLUSION_FILTER);
}
protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
if (!this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
ConfigurationClass existingClass = (ConfigurationClass)this.configurationClasses.get(configClass);
if (existingClass != null) {
if (configClass.isImported()) {
if (existingClass.isImported()) {
existingClass.mergeImportedBy(configClass);
}
return;
}
this.configurationClasses.remove(configClass);
this.knownSuperclasses.values().removeIf(configClass::equals);
}
SourceClass sourceClass = this.asSourceClass(configClass, filter);
do {
// 解析 循环解析自己,然后解析父类(如果父类是配置类的话)
sourceClass = this.doProcessConfigurationClass(configClass, sourceClass, filter);
} while(sourceClass != null);
this.configurationClasses.put(configClass, configClass);
}
}
doProcessConfigurationClass 对配置类进行解析:
对@ComponentScans ,@Import,@Bean ,PropertySources ,@@Configuration 进行解析 生成bean 定义
// 对配置类进行解析
@Nullable
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter) throws IOException {
// 如果被 Component 注解修饰
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// 解析内部类 如果是配置类则进行解析
this.processMemberClasses(configClass, sourceClass, filter);
}
// 对@PropertySources 进行解析
Iterator var4 = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), PropertySources.class, PropertySource.class).iterator();
AnnotationAttributes importResource;
while(var4.hasNext()) {
importResource = (AnnotationAttributes)var4.next();
if (this.environment instanceof ConfigurableEnvironment) {
// 把 property 的key-value 资源放入到 spring 系统环境中
this.processPropertySource(importResource);
} else {
this.logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() + "]. Reason: Environment must implement ConfigurableEnvironment");
}
}
// 解析@ComponentScans
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
Iterator var14 = componentScans.iterator();
while(var14.hasNext()) {
AnnotationAttributes componentScan = (AnnotationAttributes)var14.next();
// 构造扫描器 通过doScan 方法 将路径下的bean 生成bean 定义并注册到工厂里
Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
Iterator var8 = scannedBeanDefinitions.iterator();
while(var8.hasNext()) {
BeanDefinitionHolder holder = (BeanDefinitionHolder)var8.next();
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
this.parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// 解析@Import
this.processImports(configClass, sourceClass, this.getImports(sourceClass), filter, true);
importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
String[] var20 = resources;
int var22 = resources.length;
for(int var23 = 0; var23 < var22; ++var23) {
String resource = var20[var23];
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
// 解析@Bean
Set<MethodMetadata> beanMethods = this.retrieveBeanMethodMetadata(sourceClass);
Iterator var18 = beanMethods.iterator();
while(var18.hasNext()) {
MethodMetadata methodMetadata = (MethodMetadata)var18.next();
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// 解析当前配置类实现的接口 有没有定义@Bean 默认方法
this.processInterfaces(configClass, sourceClass);
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
return sourceClass.getSuperClass();
}
}
return null;
}
配置类解析的过程:
@Configuration 是full 配置类 @Component 是lite 配置类,@Configuration 会为该类生成代理对象,通过拦截方法,进行功能的强化;
在类中如果有@Bean 方法,该类被Configuration 修饰直接调用方法,通过代理对象调用方法,此时会先从从容器中getBean 获取对象的bean 如果获取到则返回,获取不到则创建bean ,并放入单例池中;
如果类被 @Component 修饰 则每次都会直接调用@Bean 方法,导致每次都直接走@Bean 方法的逻辑,每次都创建一个新的对象进行返回;
// @Component
@Configuration
public class MyConfig {
@Bean
public UserService userService(){
System.out.println("orderService() = " + orderService());
System.out.println("orderService() = " + orderService());
System.out.println("orderService() = " + orderService());
return new UserService();
}
@Bean
public OrderService orderService(){
return new OrderService();
}
}
@Component (“x”) 定义相同名称的bean 在扫描生成bean 定义时 直接报错;
@Bean 定义多个类型和名称相同的bean,不会报错,只会产生一个bean 的定义,生成bean 的时候通过推断构造方法来选择进行调用生成bean;
@Component 和 @Bean 定义相同类型和名称相同的bean,@Bean 会覆盖掉@Component 的bean 定义;
springboot 在启动时 只加了@SpringBootApplication 并没有定义扫描路径,它是如何知晓要去哪里进行扫描并生成bean?
在Spring Boot应中,当你使用@SpringBootApplication注解标记主类时,并没有显式指定扫描路径。那么Spring Boot是如何知晓要去哪里进行扫描并生成Bean呢?
@SpringBootApplication注解实际上是一个组合注解,包含了多个注解,其中之一就是@ComponentScan。@ComponentScan注解用于指定要扫描的包路径。当你没有显式指定扫描路径时,@ComponentScan会默认扫描主类所在包及其子包下的所有类。
换句话说,当你使用@SpringBootApplication注解标记主类时,默认情况下,Spring Boot会递归地扫描主类所在包及其子包下的所有类,并将其注册为Bean。
此外,还有一个重要的注解是@EnableAutoConfiguration。@EnableAutoConfiguration注解会根据其依赖的类自动配置机制,根据类路径中的jar包、类文件等自动进行配置。这样,Spring Boot就能够自动根据项目的依赖来配置相应的Bean。
综上所述,当你在Spring Boot应用的主类上标记@SpringBootApplication注解时,Spring Boot会根据默认规则(即主类所在包及其子包下的所有类)进行扫描和生成Bean。同时,使用@EnableAutoConfiguration注解进行自动配置,帮助快速搭建应用程序的基础配置。
spring 启动过程中,先进行beanFactory 的创建,然后通过ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry 方法进行配置类的解析并生成bean 定义,最后通过 this.finishBeanFactoryInitialization(beanFactory) 根据定义的bean 完成非懒加载的bean 创建。