美文网首页Spring
spring ioc源码解析(bean定义加载)

spring ioc源码解析(bean定义加载)

作者: 為妳奮閗 | 来源:发表于2020-06-11 15:16 被阅读0次

    最近学习了一段时间spring 源码,写一些学习笔记,大家互相交流一下。

    spring 容器的启动过程,主要做了两件事情,beanDefinition的加载 和 bean的创建

    首先我们来看下beanFactory 接口的继承图 beanFactory继承图.png

    在接下来的源码分析中,我们分析两个类 AnnotationConfigApplicationContext, DefaultListableBeanFactory

    AnnotationConfigApplicationContext这个类是基于注解的容器类,它实现了BeanFactory和BeanDefinitionRegistry两个接口,拥有bean对象管理和beanDefinition注册的功能,同时在这个类里边还拥有一个DefaultListableBeanFactory 对象。

    DefaultListableBeanFactory 这个类也实现了BeanFactory和BeanDefinitionRegistry两个接口,拥有bean对象管理和beanDefinition注册的功能,AnnotationConfigApplicationContext是委托DefaultListableBeanFactory来实现bean对象管理和beanDefinition的注册。

    beanDefinition的加载

    beanDefition个是一个接口,是用来存储Bean定义的一些信息的,比如ClassName,Scope,init-methon,等等。它的实现有RootBeanDefination,AnnotatedGenericBeanDefinition等。

    首先我们通过一个小的demo,来启动一个spring容器。

      public static void main(String[] args) {
            AnnotationConfigApplicationContext cxt = new AnnotationConfigApplicationContext(MainConfig.class);
            Car car = (Car) cxt.getBean("car");
            System.out.println(car.getName());
        }
    
      @Configuration
      @Import(value = {TimeProxy.class,LogProxy.class})
      @ComponentScan(value = "com.thread.proyx")
      public class MainConfig {
        @Bean
        public Car car(){
            return new Car();
        }
        @Bean
        public Tran tran(){
            return new Tran();
        }
      }
    

    接下来我们对源码进行分析,创建AnnotationConfigApplicationContext对象

     public AnnotationConfigApplicationContext(Class... componentClasses) {
            //加载spring内部类的beanDefinition到容器中
            this();
            //加载配置类的beanDefinition
            this.register(componentClasses);
            //加载其它类beanDefinition,创建bean实例化...
            this.refresh();
        }
    

    this构造方法,给我们创建了AnnotatedBeanDefinitionReader注解bean定义读取,ClassPathBeanDefinitionScanner 类路径bean定义扫描器,还有它的父类构造方法,创建了 DefaultListableBeanFactory 对象,

    public AnnotationConfigApplicationContext() {
    
        this.reader = new AnnotatedBeanDefinitionReader(this);
    
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }
    //父类构造器
    public GenericApplicationContext() {
    
        this.customClassLoader = false;
    
        this.refreshed = new AtomicBoolean();
    
    //创建beanFactory
    
        this.beanFactory = new DefaultListableBeanFactory();
    
    }
    

    AnnotatedBeanDefinitionReader对象的创建,是用来加载spring内部类的beanDefinition,我们从源码可以看出

     public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
            //省略一些代码...
            //注册注解形式的配置处理器
            AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
        }
    
     public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {
            //判断registry是否为空
            DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
           //省略配置beanFactory的一些代码
    
            Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet(8);
            RootBeanDefinition def;
            //ConfigurationClassPostProcessor类型的beanDefinition注册到容器中,这个类型很重要,接下来,我们自己注入的类,通过扫描器扫描的类,解析方法就在这个类里边。
            if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalConfigurationAnnotationProcessor")) {
                def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"));
            }
            //解析autowired自动装配的beanDefinition注册到容器中(这是个后置处理器)
            if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalAutowiredAnnotationProcessor")) {
                def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"));
            }
            //省略了一些代码(spring内部需要注册到容器中的beanDefinition)
            return beanDefs;
        }
    

    到这里,我们的AnnotatedBeanDefinitionReader对象就创建完成了,AnnotatedBeanDefinitionReader对象的创建过程,就是将spring内部的一些处理器的beanDefinition加载到容器中。

    ClassPathBeanDefinitionScanner(类路径bean定义扫描器)对象的创建,就是创建默认的扫描器,代码比较简单。this方法已经完成,主要就是加载spring内部类的beanDefinition到容器中。

    registe方法,传入的参数,就是我们创建的配置类,这个方法是把我们配置类的beanDefinition加载到容器中

        public void register(Class... componentClasses) {
            Assert.notEmpty(componentClasses, "At least one component class must be specified");
            //this方法创建的reader对象,调用register方法,传入配置类
            this.reader.register(componentClasses);
        }
    
        public void register(Class... componentClasses) {
            Class[] var2 = componentClasses;
            int var3 = componentClasses.length;
            for(int var4 = 0; var4 < var3; ++var4) {
                Class<?> componentClass = var2[var4];
            //调用注册配置类的beanDefinition
                this.registerBean(componentClass);
            }
        }
    
       public void registerBean(Class<?> beanClass) {
            this.doRegisterBean(beanClass, (String)null, (Class[])null, (Supplier)null, (BeanDefinitionCustomizer[])null);
        }
    
        
        private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier, @Nullable BeanDefinitionCustomizer[] customizers) {
            AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
             //省略一些代码
                //创建beanDefinition的包装类
                BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
                definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
                //继续调用注册bean定义方法
                BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
            }
        }
    
        public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
            String beanName = definitionHolder.getBeanName();
            //BeanDefinitionRegistry 是接口,调用方法实现类的方法,前面说到DefaultListableBeanFactory 实现了该接口,直接调用 DefaultListableBeanFactory  的registerBeanDefinition 方法
            registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
            String[] aliases = definitionHolder.getAliases();
            //配置别名
            if (aliases != null) {
                String[] var4 = aliases;
                int var5 = aliases.length;
                for(int var6 = 0; var6 < var5; ++var6) {
                    String alias = var4[var6];
                    registry.registerAlias(beanName, alias);
                }
            }
        }
    
    //在 DefaultListableBeanFactory的 registerBeanDefinition方法中有端代码
    
    this.beanDefinitionMap.put(beanName, beanDefinition);
    

    说明了把beanDefinition保存在 map中,beanName为key,beanDefinition为value;这里是把配置类的bean定义注册到容器中;到这里 registe方法就完成了,当前只是把配置类的bean定义注册完成。我们自己注入的bean,扫描的bean定义还没有加载。

    AnnotationConfigApplicationContext的最后一个方法 refresh,这里边是注册@bean,@ComponentScan, @Import 等注入的beanDefinition,创建bean实例等操作。

     public void refresh() throws BeansException, IllegalStateException {
            synchronized(this.startupShutdownMonitor) {
                this.prepareRefresh();
                ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
                this.prepareBeanFactory(beanFactory);
                try {
                    this.postProcessBeanFactory(beanFactory);
                    //这个方法很重要,其它beanDefinition注册,都在这里边实现,本篇接下来主要介绍这个方法的实现。
                    this.invokeBeanFactoryPostProcessors(beanFactory);
                    //注册bean后置处理器,aop用到
                    this.registerBeanPostProcessors(beanFactory);
                    this.initMessageSource();
                    //初始化事件多播器,事件监听使用
                    this.initApplicationEventMulticaster();
                    this.onRefresh();
                    //事件监听器
                    this.registerListeners();
                    //这个方法很重要,完成bean实例化的创建,包括解决循环依赖,这篇里边不做介绍,
                    this.finishBeanFactoryInitialization(beanFactory);
                    this.finishRefresh();
                } catch (BeansException var9) {
                    if (this.logger.isWarnEnabled()) {
                        this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                    }
                    this.destroyBeans();
                    this.cancelRefresh(var9);
                    throw var9;
                } finally {
                    this.resetCommonCaches();
                }
            }
        }
    

    接下来看下我们来看invokeBeanFactoryPostProcessors(beanFactory)方法里边的源码

        protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
            //传入参数beanFactory和 beanFactory后置处理器
            PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());
            //省略一些代码
        }
    
        public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
                //其它省略的代码,一些看不懂,
                //这个方法是最主要的处理方法,继续调用,还没有进去到处理的地方
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();
               
        private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
            Iterator var2 = postProcessors.iterator();
            while(var2.hasNext()) {
                BeanDefinitionRegistryPostProcessor postProcessor = (BeanDefinitionRegistryPostProcessor)var2.next();
                //这里就是调用ConfigurationClassPostProcessor类里边的方法,ConfigurationClassPostProcessor就是刚开始注册的那个很重要的内部bean定义
                postProcessor.postProcessBeanDefinitionRegistry(registry);
            }
        }
    
    //这里就是ConfigurationClassPostProcessor的方法
      public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
              //省略一些代码
                this.registriesPostProcessed.add(registryId);
                //这里才是处理配置bean定义的主要方法,接着往下看
                this.processConfigBeanDefinitions(registry);
        }
    
        public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
                 //省略一些配置的代码
                //创建配置类的解析器
                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 {
                    //解析配置类里边@ComponentScan 注解扫描的bean,加载beanDefinition到容器中,并找到@bean,@Import 等注解引入的bean
                    parser.parse(candidates);
                    //把上面找到但没有加载的bean定义,加载到容器中
                    this.reader.loadBeanDefinitions(configClasses);
                  }while(!candidates.isEmpty())
                   
        }
    

    接下来我们看下parse方法里边的源码,

       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) {
                    //注解的bean定义,从这个方法进入
                        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(AnnotationMetadata metadata, String beanName) throws IOException {
            this.processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
        }
    
        protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
                do {
                  //这里是spring做事的处理方法
                    sourceClass = this.doProcessConfigurationClass(configClass, sourceClass, filter);
                } while(sourceClass != null);
                this.configurationClasses.put(configClass, configClass);
        }
    
        @Nullable
        protected final ConfigurationClassParser.SourceClass doProcessConfigurationClass(ConfigurationClass configClass, ConfigurationClassParser.SourceClass sourceClass, Predicate<String> filter) throws IOException {
          
            // 处理 @ComponentScan 注解类,重点,先获取加了@ComponentScan注解的配置类
            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();
                     // 开始扫描指定package下的所有Bean,那些加了@Component,@Service,@Repository等注解的类,都会加进来。
                    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导入的beanDefinition
            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导入的beanDefinition
            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;
        }
    
    
    
        public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
            //创建扫描器
            ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry, componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
            //省略代码
            //开始扫描,将扫描的BeanDefinitionHolder返回
            return scanner.doScan(StringUtils.toStringArray(basePackages));
        }
    
    protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
            Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
            for (String basePackage : basePackages) {
                // 找出当前包下面的所有符合条件的类,这个方法我们就不分析了。
                Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
                for (BeanDefinition candidate : candidates) {
                    // 处理一些其他情况,也不说了...
                    if (candidate instanceof AbstractBeanDefinition) {
                        postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
                    }
                    if (candidate instanceof AnnotatedBeanDefinition) {
                        AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
                    }
                    if (checkCandidate(beanName, candidate)) {
                        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
                        definitionHolder =
                                AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
                        beanDefinitions.add(definitionHolder);
                        // 最后注册BeanDefinition,这样就将包下的所有BeanDefintion都注册完成了
                        registerBeanDefinition(definitionHolder, this.registry);
                    }
                }
            }
            return beanDefinitions;
        }
    

    到这里为止,我们配置类的分析就结束了,将扫描的包下的BeanDefinition都注册完成了,接下来我们看下其它方式导入的beanDefinition的注册方法
    this.reader.loadBeanDefinitions(configClasses);

    private void loadBeanDefinitionsForConfigurationClass(
                ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
            // 处理Imported的配置类
            if (configClass.isImported()) {
                registerBeanDefinitionForImportedConfigurationClass(configClass);
            }
            for (BeanMethod beanMethod : configClass.getBeanMethods()) {
                // 注册所有的@Bean方法上的类,重点看一下这个方法
                loadBeanDefinitionsForBeanMethod(beanMethod);
            }
    
            // 处理其它注解,这里就不分析了。
            loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
                     loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
        }
    
    private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
            ConfigurationClass configClass = beanMethod.getConfigurationClass();        
            // 一些别名处理的代码都省略了...
    
            //  创建BeanDefinition
            ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata);
    
            // 处理initMethod和destroyMethod
            String initMethodName = bean.getString("initMethod");
            if (StringUtils.hasText(initMethodName)) {
                beanDef.setInitMethodName(initMethodName);
            }
    
            String destroyMethodName = bean.getString("destroyMethod");
            beanDef.setDestroyMethodName(destroyMethodName);        
    
            // Replace the original bean definition with the target one, if necessary
            BeanDefinition beanDefToRegister = beanDef;
            // 最后注册这个BeanDefinition
            this.registry.registerBeanDefinition(beanName, beanDefToRegister);
        }
    
    

    到这里,所有的beanDefinition全部注册完成

    总结
    spring 注册beanDefinition,首先是注册spring内部的bean,接着是注册我们编写的配置类,最后我们通过对配置类的扫描,加载扫描的所有beanDefinition。
    我也是第一次写这么多东西,如果有哪些地方有问题,还希望跟各位多多交流。

    相关文章

      网友评论

        本文标题:spring ioc源码解析(bean定义加载)

        本文链接:https://www.haomeiwen.com/subject/xefbtktx.html