spring IoC 容器的加载过程
1.实例化容器: AnnotationConfigApplicationContext
- 实例化工厂: DefauiltListableBeanFactory
- 实例化创建BeanDefinition 读取其: AnnotatedBeanDefinitionReader
- 创建BeanDefinition 扫描器: ClassPathBeanDefinitionScanner
- 注册配置类为BeanDefinition :register(annotatedClasses)
- refresh()
- invokeBeanFactoryPostProcessors(beanFactory)
- finishBeanFactoryInitialization(beanFactory)
AnnotationConfigApplicationContext
1.1 spring boot 实例化 ApplicationContext
在 springBootApplication 启动进入 SpringApplication 类 public ConfigurableApplicationContext run(String... args) { // 创建 ApplicationContext context = this.createApplicationContext(); }
跟踪该方法:使用applicationContextFactory 创建 一个ApplicationContext
protected ConfigurableApplicationContext createApplicationContext() { return this.applicationContextFactory.create(this.webApplicationType); }
继续跟踪进入 ApplicationContextFactory 类,该类会根据项目的webApplicationType 创建不同的ApplicationContext 。
@FunctionalInterface public interface ApplicationContextFactory { ApplicationContextFactory DEFAULT = (webApplicationType) -> { try { switch(webApplicationType) { case SERVLET: return new AnnotationConfigServletWebServerApplicationContext(); case REACTIVE: return new AnnotationConfigReactiveWebServerApplicationContext(); default: return new AnnotationConfigApplicationContext(); } } catch (Exception var2) { throw new IllegalStateException("Unable create a default ApplicationContext instance, you may need a custom ApplicationContextFactory", var2); } }; ConfigurableApplicationContext create(WebApplicationType webApplicationType); }
根据 ApplicationContextFactory 可知,springboot 会默认创建一个AnnotationConfigApplicationContext 的spring 容器。
这里解析AnnotationConfigApplicationContext 类的Ioc容器加载过程。
1.2 进入AnnotationConfigApplicationContext 类
1.1 中会根据webApplicationType创建一个对应的无参构造的AnnotationConfigApplicationContext实例对象: public AnnotationConfigApplicationContext() { StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create"); // 进行初始化 this.reader = new AnnotatedBeanDefinitionReader(this); createAnnotatedBeanDefReader.end(); this.scanner = new ClassPathBeanDefinitionScanner(this); } 在实例化AnnotationConfigApplicationContext 对象时,会先调用父类GenericApplicationContext的构造函数。父类的构造函数里面就是初始化DefaultListableBeanFactory,并且赋值给beanFactory 。 public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry { private final DefaultListableBeanFactory beanFactory; @Nullable private ResourceLoader resourceLoader; private boolean customClassLoader; private final AtomicBoolean refreshed; public GenericApplicationContext() { // 实例化工厂:DefaultListableBeanFactory // DefaultListableBeanFactory是相当重要的,用来生产 和获得Bean的。 this.beanFactory = new DefaultListableBeanFactory(); } } 本类的构造函数里面,初始化了一个读取器:AnnotatedBeanDefinitionReader read,一个扫描器ClassPathBeanDefinitionScanner scanner。scanner的用处不是很大,它仅仅是在我们外部手动调用 .scan 等方法才有用,常规方式是不会用到scanner对象的。 让我们看看Spring在初始化 AnnotatedBeanDefinitionReader的时候做了什么: public class AnnotatedBeanDefinitionReader { private final BeanDefinitionRegistry registry; private BeanNameGenerator beanNameGenerator; private ScopeMetadataResolver scopeMetadataResolver; private ConditionEvaluator conditionEvaluator; // 在AnnotationConfigApplicationContext 初始化 AnnotatedBeanDefinitionReader进入该构造方法,registry 为 在AnnotationConfigApplicationContext的实例 public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) { // 调用该类的其他构造方法 this(registry, getOrCreateEnvironment(registry)); } public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) { this.beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE; this.scopeMetadataResolver = new AnnotationScopeMetadataResolver(); Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); Assert.notNull(environment, "Environment must not be null"); this.registry = registry; this.conditionEvaluator = new ConditionEvaluator(registry, environment, (ResourceLoader)null); AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); } } 其中registerAnnotationConfigProcessors 会注册spring 内置的多个bean 。跟踪该方法,贴出最核心的代码: public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) { if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalConfigurationAnnotationProcessor")) { def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source); // registerPostProcessor 注册Bean beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalConfigurationAnnotationProcessor")); } }
- 判断容器中是否已经存在了ConfigurationClassPostProcessor Bean
- 如果不存在(当然这里肯定是不存在的),就通过RootBeanDefinition的构造方法获得
ConfigurationClassPostProcessor的BeanDefinition,RootBeanDefinition是BeanDefinition的子类
- 执行registerPostProcessor方法,registerPostProcessor方法内部就是注册Bean,当然这里注册
其他Bean也是一样的流程。
BeanDefinition它是用来描述Bean的,里面存放着关于Bean的一系列信息,比如Bean的作用域,Bean所对应的Class,是 否懒加载,是否Primary等等,这个BeanDefinition也相当重要,我们以后会常常和它打交道。
继续追踪registerPostProcessor 方法,注册bean private static BeanDefinitionHolder registerPostProcessor(BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) { definition.setRole(2); registry.registerBeanDefinition(beanName, definition); return new BeanDefinitionHolder(definition, beanName); }
继续追踪registerBeanDefinition 方法,其中的核心实现是DefaultListableBeanFactory
//beanDefinitionMap是Map<String, BeanDefinition>, //这里就是把beanName作为key,ScopedProxyMode作为value,推到map里面 this.beanDefinitionMap.put(beanName, beanDefinition); //beanDefinitionNames就是一个List<String>,这里就是把beanName放到List中去 this.beanDefinitionNames.add(beanName);
从这里可以看出DefaultListableBeanFactory就是我们所说的容器了,里面放着beanDefinitionMap,**
beanDefinitionNames,beanDefinitionMap是一个hashMap,beanName作为Key,beanDefinition作
为Value,beanDefinitionNames是一个集合,里面存放了beanName。
ConfigurationClassPostProcessor实现BeanDefinitionRegistryPostProcessor接口,
BeanDefinitionRegistryPostProcessor接口又扩展了BeanFactoryPostProcessor接口,
BeanFactoryPostProcessor是Spring的扩展点之一,ConfigurationClassPostProcessor是Spring极
为重要的一个类
4.创建BeanDefinition扫描器:ClassPathBeanDefinitionScanner
由于常规使用方式是不会用到AnnotationConfigApplicationContext里面的scanner的,这里的scanner
仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法。所以这里就不看
scanner是如何被实例化的了。
5.注册配置类为BeanDefinition: register(annotatedClasses);
public AnnotationConfigApplicationContext(Class<?>... componentClasses) { this(); this.register(componentClasses); this.refresh(); }
一直跟踪 register 方法:
AnnotationConfigApplicationContext. register(Class<?>... componentClasses)
------>AnnotatedBeanDefinitionReader.register(Class<?>... componentClasses)
------>AnnotatedBeanDefinitionReader.registerBean(Class<?> beanClass)
------->AnnotatedBeanDefinitionReader.doRegisterBean
查看doRegisterBean 方法的实现
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier, @Nullable BeanDefinitionCustomizer[] customizers) { //AnnotatedGenericBeanDefinition可以理解为一种数据结构,是用来描述Bean的,这里的作用就是把传入的标记了注解 的类 //转为AnnotatedGenericBeanDefinition数据结构,里面有一个getMetadata方法,可以拿到类上的注解 AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass); //判断是否需要跳过注解,spring中有一个@Condition注解,当不满足条件,这个bean就不会被解析 if (!this.conditionEvaluator.shouldSkip(abd.getMetadata())) { abd.setInstanceSupplier(supplier); //解析bean的作用域,如果没有设置的话,默认为单例 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd); abd.setScope(scopeMetadata.getScopeName()); String beanName = name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry); //解析通用注解,填充到AnnotatedGenericBeanDefinition,解析的注解为Lazy,Primary,DependsOn,Role,Descri ption AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); int var10; int var11; if (qualifiers != null) { Class[] var9 = qualifiers; var10 = qualifiers.length; for(var11 = 0; var11 < var10; ++var11) { Class<? extends Annotation> qualifier = var9[var11]; //Primary注解优先 if (Primary.class == qualifier) { abd.setPrimary(true); //Lazy注解 } else if (Lazy.class == qualifier) { abd.setLazyInit(true); } else { //其他,AnnotatedGenericBeanDefinition有个Map<String,AutowireCandidateQualifier>属性,直接push进去 abd.addQualifier(new AutowireCandidateQualifier(qualifier)); } } } BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); //注册,最终会调用DefaultListableBeanFactory中的registerBeanDefinition方法去注册, //DefaultListableBeanFactory维护着一系列信息,比如beanDefinitionNames,beanDefinitionMap //beanDefinitionNames是一个List<String>,用来保存beanName //beanDefinitionMap是一个Map,用来保存beanName和beanDefinition BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); } }
重点跟踪 BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry)**该方法,该方法最终实现bean 的注册。
最终会调用DefaultListableBeanFactory中的registerBeanDefinition方法去注册:
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { BeanDefinition existingDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName); if (existingDefinition != null) { // 是否对已存在的bean 进行重写 if (!this.isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition); } } else { // 如果注册的bean 不存在,则进行注册 if (this.hasBeanCreationStarted()) { synchronized(this.beanDefinitionMap) { this.beanDefinitionMap.put(beanName, beanDefinition); List<String> updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; this.removeManualSingletonName(beanName); } } else { this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); this.removeManualSingletonName(beanName); } this.frozenBeanDefinitionNames = null; } }
到这里注册配置类也分析完毕了。
- refresh()
大家可以看到其实到这里,Spring还没有进行扫描,只是实例化了一个工厂,注册了一些内置的Bean和我
们传进去的配置类,真正的大头是在第三行代码
public AnnotationConfigApplicationContext(Class<?>... componentClasses) { this(); this.register(componentClasses); this.refresh(); }
这个方法做了很多事情,让我们点开这个方法:
public void refresh() throws BeansException, IllegalStateException { synchronized(this.startupShutdownMonitor) { StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh"); //刷新预处理,和主流程关系不大,就是保存了容器的启动时间,启动标志等 this.prepareRefresh(); //和主流程关系也不大,最终获得了DefaultListableBeanFactory, ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); //还是一些准备工作,添加了两个后置处理器:ApplicationContextAwareProcessor,ApplicationListenerDetector //还设置了 忽略自动装配 和 允许自动装配 的接口,如果不存在某个bean的时候,spring就自动注册singleton bean //还设置了bean表达式解析器 等 this.prepareBeanFactory(beanFactory); try { //这是一个空方法,用于扩展 this.postProcessBeanFactory(beanFactory); StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process"); //执行自定义的 BeanFactoryProcessor 和内置的 BeanFactoryProcessor this.invokeBeanFactoryPostProcessors(beanFactory); // 注册BeanPostProcessor this.registerBeanPostProcessors(beanFactory); beanPostProcess.end(); this.initMessageSource(); this.initApplicationEventMulticaster(); // 空方法 this.onRefresh(); this.registerListeners(); // 实例化所有剩余的(非懒加载)单例 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(); } } }
6.1 跟踪prepareBeanFactory 方法,该方法用于添加一些解析器和自动装配的配置,比较重要
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { beanFactory.setBeanClassLoader(this.getClassLoader()); if (!shouldIgnoreSpel) { //设置bean表达式解析器 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); } //属性编辑器支持 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment())); //添加一个后置处理器:ApplicationContextAwareProcessor,此后置处理处理器实现了BeanPostProcessor接口 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); //以下接口,忽略自动装配 beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); beanFactory.ignoreDependencyInterface(ApplicationStartup.class); beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); if (!IN_NATIVE_IMAGE && beanFactory.containsBean("loadTimeWeaver")) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } if (!beanFactory.containsLocalBean("environment")) { beanFactory.registerSingleton("environment", this.getEnvironment()); } if (!beanFactory.containsLocalBean("systemProperties")) { beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean("systemEnvironment")) { beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment()); } if (!beanFactory.containsLocalBean("applicationStartup")) { beanFactory.registerSingleton("applicationStartup", this.getApplicationStartup()); } }
以上方法做的主要操作如下:
- 设置了一个类加载器
- 设置了bean表达式解析器
- 添加了属性编辑器的支持
- 添加了一个后置处理器:ApplicationContextAwareProcessor,此后置处理器实现了BeanPostProcessor接口
- 设置了一些忽略自动装配的接口
- 设置了一些允许自动装配的接口,并且进行了赋值操作
- 在容器中还没有XX的bean的时候,帮我们注册beanName为XX的singleton bean
6.2 invokeBeanFactoryPostProcessors该方法也比较重要,执行自定义的BeanFactoryProcessor和内置的BeanFactoryProcessor 。其体现了spring 的可扩展性及热插拔属性。该方法会查找实现了BeanFactoryPostProcessor的后置处理器,并且执行后置处理器中的方法。
查看ConfigurationClassPostProcessor中对BeanDefinitionRegistryPostProcessor。postProcessBeanDefinitionRegistry方法的实现 public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { // 生成一个注册的Id 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); this.processConfigBeanDefinitions(registry); } }
继续跟踪processConfigBeanDefinitions(registry)方法,并解析该方法的实现逻辑
该方法主要用于解析带有 @Configuration 的每一个注解类: public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { List<BeanDefinitionHolder> configCandidates = new ArrayList(); //获得所有的BeanDefinition的Name 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)) { 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; // DefaultListableBeanFactory最终会实现SingletonBeanRegistry接口,所以可以进入到这个if 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); HashSet alreadyParsed = new HashSet(configCandidates.size()); do { StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse"); //解析配置类(传统意义上的配置类或者是普通bean,核心来了) 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()); } //直到这一步才把Import的类,@Bean @ImportRosource 转换 成BeanDefinition this.reader.loadBeanDefinitions(configClasses); alreadyParsed.addAll(configClasses); processConfig.tag("classCount", () -> { return String.valueOf(configClasses.size()); }).end(); candidates.clear(); //获得注册器里面BeanDefinition的数量 和 candidateNames进行比较 //如果大于的话,说明有新的BeanDefinition注册进来了 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(!candidates.isEmpty()); } }
该方法中的ConfigurationClassUtils.checkConfigurationClassCandidate 这个方法会对添加有Full 与Lite 两个标记位的注解进行解析判断:
当我们注册配置类的时候,可以不加Configuration注解,直接使用Component ComponentScan Import ImportResou rce注解,称之为Lite配置类 。 如果加了Configuration注解,就称之为Full配置类。
重点跟踪上面方法中的parser.parse(candidates) 方法,一直点击进去直到 ConfigurationClassParser 。doProcessConfigurationClass 方法
@Nullable protected final ConfigurationClassParser.SourceClass doProcessConfigurationClass(ConfigurationClass configClass, ConfigurationClassParser.SourceClass sourceClass, Predicate<String> filter) throws IOException { //递归处理内部类,一般不会写内部类 this.processMemberClasses(configClass, sourceClass, filter); //处理@PropertySource注解,@PropertySource注解用来加载properties文件 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) { this.processPropertySource(importResource); } else { this.logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() + "]. Reason: Environment must implement ConfigurableEnvironment"); } } //获得ComponentScan注解具体的内容,ComponentScan注解除了最常用的basePackage之外,还有includeFilters,excludeFilters等 Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class); //如果没有打上ComponentScan,或者被@Condition条件跳过,就不再进入这个if if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) { Iterator var14 = componentScans.iterator(); //循环处理componentScans while(var14.hasNext()) { AnnotationAttributes componentScan = (AnnotationAttributes)var14.next(); 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注解 //@Import注解是spring中很重要的一个注解,Springboot大量应用这个注解 //@Import三种类,一种是Import普通类,一种是Import ImportSelector,还有一种是Import ImportBeanDefinitionR egistrar 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的方法,可以看到获得了带有@Bean的方法后,不是马上转换成BeanDefinition,而是先用一个set接收 Set<MethodMetadata> beanMethods = this.retrieveBeanMethodMetadata(sourceClass); Iterator var18 = beanMethods.iterator(); while(var18.hasNext()) { MethodMetadata methodMetadata = (MethodMetadata)var18.next(); configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass)); } 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; }
实现的逻辑顺序:
- 递归处理内部类,一般不会使用内部类。
- 处理@PropertySource注解,@PropertySource注解用来加载properties文件。
- 获得ComponentScan注解具体的内容,ComponentScan注解除了最常用的basePackage之外,还有includeFilters,
excludeFilters等。
- 判断有没有被@ComponentScans标记,或者被@Condition条件带过,如果满足条件的话,进入if,进行如下操作:
4.1 执行扫描操作,把扫描出来的放入set,这个方法稍后再详细说明。
4.2 循环set,判断是否是配置类,是的话,递归调用parse方法,因为被扫描出来的类,还是一个配置类,有@ComponentScans注解,
或者其中有被@Bean标记的方法 等等,所以需要再次被解析。
- 处理@Import注解,@Import是Spring中很重要的一个注解,正是由于它的存在,让Spring非常灵活,不管是Spring内部,还 是与Spring整合的第三方技术,都大量的运用了@Import注解,@Import有三种情况,一种是Import普通类,一种是ImportSelector,还有一种是Import ImportBeanDefinitionRegistrar,getImports(sourceClass)是获得import的内容,返回的 是一个set。
- 处理@ImportResource注解。
- 处理@Bean的方法,可以看到获得了带有@Bean的方法后,不是马上转换成BeanDefinition,而是先用一个set接收。
6.6-registerBeanPostProcessors(beanFactory);
实例化和注册beanFactory中扩展了BeanPostProcessor的bean。
例如:
AutowiredAnnotationBeanPostProcessor(处理被@Autowired注解修饰的bean并注入)
RequiredAnnotationBeanPostProcessor(处理被@Required注解修饰的方法)
CommonAnnotationBeanPostProcessor(处理@PreDestroy、@PostConstruct、@Resource等多个注解的作用)等。
6-11-finishBeanFactoryInitialization(beanFactory);
实例化所有剩余的(非懒加载)单例
比如invokeBeanFactoryPostProcessors方法中根据各种注解解析出来的类,在这个时候都会被初始化。
实例化的过程各种BeanPostProcessor开始起作用。
finishBeanFactoryInitialization(beanFactory);
这个方法是用来实例化懒加载单例Bean的,也就是我们的Bean都是在这里被创建出来的
一直跟踪该方法,该方法也非常重要:
finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory)
----〉 AbstractApplicationContext.getBean(String name)
------> 直到AbstractBeanFactory。doGetBean (AbstractBeanFactory也是核心类,非常重要)
if (mbd.isSingleton()) { sharedInstance = this.getSingleton(beanName, () -> { try { return this.createBean(beanName, mbd, args); } catch (BeansException var5) { this.destroySingleton(beanName); throw var5; } }); bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
继续跟踪其中的createBean 方法直到doCreateBean 方法。
// 1.创建bean的实例。核心 instanceWrapper = createBeanInstance(beanName, mbd, args); // 2。填充属性 populateBean(beanName, mbd, instanceWrapper);//填充属性,炒鸡重要 // 3.进行aware系列接口的回调,并进行初始化方法 exposedObject = initializeBean(beanName, exposedObject, mbd); // 4. 执行BeanPostProcessor的postProcessBeforeInitialization方法 if (mbd == null || !mbd.isSynthetic()) { wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } //5. afterPropertiesSet init-method位于initializeBean中的 invokeInitMethods(beanName, wrappedBean, mbd);
Spring Bean的生命周期
- 实例化Bean对象,这个时候Bean的对象是非常低级的,基本不能够被我们使用,因为连最基本的属性都没有设置,可以理解为 连Autowired注解都是没有解析的;
- 填充属性,当做完这一步,Bean对象基本是完整的了,可以理解为Autowired注解已经解析完毕,依赖注入完成了;
- 如果Bean实现了BeanNameAware接口,则调用setBeanName方法;
- 如果Bean实现了BeanClassLoaderAware接口,则调用setBeanClassLoader方法;
- 如果Bean实现了BeanFactoryAware接口,则调用setBeanFactory方法;
- 调用BeanPostProcessor的postProcessBeforeInitialization方法;
- 如果Bean实现了InitializingBean接口,调用afterPropertiesSet方法;
- 如果Bean定义了init-method方法,则调用Bean的init-method方法;
- 调用BeanPostProcessor的postProcessAfterInitialization方法;当进行到这一步,Bean已经被准备就绪了,一直停留在应用的
上下文中,直到被销毁;
- 如果应用的上下文被销毁了,如果Bean实现了DisposableBean接口,则调用destroy方法,如果Bean定义了destory-method
声明了销毁方法也会被调用。
6-12-finishRefresh();
refresh做完之后需要做的其他事情。
清除上下文资源缓存(如扫描中的ASM元数据)
初始化上下文的生命周期处理器,并刷新(找出Spring容器中实现了Lifecycle接口的bean并执行start()方法)。
发布ContextRefreshedEvent事件告知对应的ApplicationListener进行响应的操作
Spring IOC源码解析(10)AbstractBeanFactory
https://www.jianshu.com/p/ef6a92ce25b3
Spring源码6:createApplicationContext()实例AnnotationConfigServletWebServerApplicationContext
https://www.jianshu.com/p/17c8b15dd595
标签: 源码