spring IoC 源码

本文涉及的产品
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
简介: spring IoC 源码

spring IoC 容器的加载过程

1.实例化容器:  AnnotationConfigApplicationContext
  1. 实例化工厂: DefauiltListableBeanFactory
  2. 实例化创建BeanDefinition 读取其: AnnotatedBeanDefinitionReader
  3. 创建BeanDefinition 扫描器: ClassPathBeanDefinitionScanner
  4. 注册配置类为BeanDefinition :register(annotatedClasses)
  5. refresh()
  6. invokeBeanFactoryPostProcessors(beanFactory)
  7. 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"));
        }
        
}
  1. 判断容器中是否已经存在了ConfigurationClassPostProcessor Bean
  2. 如果不存在(当然这里肯定是不存在的),就通过RootBeanDefinition的构造方法获得

ConfigurationClassPostProcessor的BeanDefinition,RootBeanDefinition是BeanDefinition的子类

  1. 执行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;
        }
}

到这里注册配置类也分析完毕了。

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

以上方法做的主要操作如下:

  1. 设置了一个类加载器
  2. 设置了bean表达式解析器
  3. 添加了属性编辑器的支持
  4. 添加了一个后置处理器:ApplicationContextAwareProcessor,此后置处理器实现了BeanPostProcessor接口
  5. 设置了一些忽略自动装配的接口
  6. 设置了一些允许自动装配的接口,并且进行了赋值操作
  7. 在容器中还没有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;
    }

实现的逻辑顺序:

  1. 递归处理内部类,一般不会使用内部类。
  2. 处理@PropertySource注解,@PropertySource注解用来加载properties文件。
  3. 获得ComponentScan注解具体的内容,ComponentScan注解除了最常用的basePackage之外,还有includeFilters,

excludeFilters等。

  1. 判断有没有被@ComponentScans标记,或者被@Condition条件带过,如果满足条件的话,进入if,进行如下操作:
    4.1 执行扫描操作,把扫描出来的放入set,这个方法稍后再详细说明。
    4.2 循环set,判断是否是配置类,是的话,递归调用parse方法,因为被扫描出来的类,还是一个配置类,有@ComponentScans注解,

或者其中有被@Bean标记的方法 等等,所以需要再次被解析。

  1. 处理@Import注解,@Import是Spring中很重要的一个注解,正是由于它的存在,让Spring非常灵活,不管是Spring内部,还 是与Spring整合的第三方技术,都大量的运用了@Import注解,@Import有三种情况,一种是Import普通类,一种是ImportSelector,还有一种是Import ImportBeanDefinitionRegistrar,getImports(sourceClass)是获得import的内容,返回的 是一个set。
  2. 处理@ImportResource注解。
  3. 处理@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的生命周期

  1. 实例化Bean对象,这个时候Bean的对象是非常低级的,基本不能够被我们使用,因为连最基本的属性都没有设置,可以理解为 连Autowired注解都是没有解析的;
  2. 填充属性,当做完这一步,Bean对象基本是完整的了,可以理解为Autowired注解已经解析完毕,依赖注入完成了;
  3. 如果Bean实现了BeanNameAware接口,则调用setBeanName方法;
  4. 如果Bean实现了BeanClassLoaderAware接口,则调用setBeanClassLoader方法;
  5. 如果Bean实现了BeanFactoryAware接口,则调用setBeanFactory方法;
  6. 调用BeanPostProcessor的postProcessBeforeInitialization方法;
  7. 如果Bean实现了InitializingBean接口,调用afterPropertiesSet方法;
  8. 如果Bean定义了init-method方法,则调用Bean的init-method方法;
  9. 调用BeanPostProcessor的postProcessAfterInitialization方法;当进行到这一步,Bean已经被准备就绪了,一直停留在应用的

上下文中,直到被销毁;

  1. 如果应用的上下文被销毁了,如果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

标签: 源码

目录
相关文章
|
24天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
64 2
|
1月前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
|
8天前
|
存储 缓存 Java
Spring面试必问:手写Spring IoC 循环依赖底层源码剖析
在Spring框架中,IoC(Inversion of Control,控制反转)是一个核心概念,它允许容器管理对象的生命周期和依赖关系。然而,在实际应用中,我们可能会遇到对象间的循环依赖问题。本文将深入探讨Spring如何解决IoC中的循环依赖问题,并通过手写源码的方式,让你对其底层原理有一个全新的认识。
24 2
|
1月前
|
前端开发 Java 开发者
Spring生态学习路径与源码深度探讨
【11月更文挑战第13天】Spring框架作为Java企业级开发中的核心框架,其丰富的生态系统和强大的功能吸引了无数开发者的关注。学习Spring生态不仅仅是掌握Spring Framework本身,更需要深入理解其周边组件和工具,以及源码的底层实现逻辑。本文将从Spring生态的学习路径入手,详细探讨如何系统地学习Spring,并深入解析各个重点的底层实现逻辑。
55 9
|
1月前
|
XML 缓存 Java
搞透 IOC、Spring IOC ,看这篇就够了!
本文详细解析了Spring框架的核心内容——IOC(控制反转)及其依赖注入(DI)的实现原理,帮助读者理解如何通过IOC实现组件解耦,提高程序的灵活性和可维护性。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
|
2月前
|
Java Spring
Spring底层架构源码解析(三)
Spring底层架构源码解析(三)
135 5
|
1月前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
35 0
|
2月前
|
XML Java 数据格式
Spring底层架构源码解析(二)
Spring底层架构源码解析(二)
|
2月前
|
XML Java 数据格式
Spring IOC容器的深度解析及实战应用
【10月更文挑战第14天】在软件工程中,随着系统规模的扩大,对象间的依赖关系变得越来越复杂,这导致了系统的高耦合度,增加了开发和维护的难度。为解决这一问题,Michael Mattson在1996年提出了IOC(Inversion of Control,控制反转)理论,旨在降低对象间的耦合度,提高系统的灵活性和可维护性。Spring框架正是基于这一理论,通过IOC容器实现了对象间的依赖注入和生命周期管理。
76 0
|
2月前
|
XML Java 数据格式
手动开发-简单的Spring基于注解配置的程序--源码解析
手动开发-简单的Spring基于注解配置的程序--源码解析
47 0