zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    golang json字符串合并操作
    goland 无法跳转 struct等
    golang 中mgo update报错: The dollar ($) prefixed field '$inc' in '$inc' is not valid for storage.
    解决windows下使用vscode没有函数提示的问题
    【转载,实测好用】gitlab结合sourcetree使用
    C++单继承、多继承情况下的虚函数表分析
    Linux 日志文件管理——限制大小
    C++ RCSP智能指针简单实现与应用
    Makefile模板(C++)
    Git关于pull,commit,push的总结
  • 原文地址:https://www.cnblogs.com/zjdxr-up/p/14579943.html
Copyright © 2011-2022 走看看