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

最近学习了一段时间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 registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {
        //判断registry是否为空
        DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
       //省略配置beanFactory的一些代码

        Set 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  void doRegisterBean(Class beanClass, @Nullable String name, @Nullable Class[] qualifiers, @Nullable Supplier 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 beanFactoryPostProcessors) {
            //其它省略的代码,一些看不懂,
            //这个方法是最主要的处理方法,继续调用,还没有进去到处理的地方
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();
           
    private static void invokeBeanDefinitionRegistryPostProcessors(Collection 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 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 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 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 filter) throws IOException {
      
        // 处理 @ComponentScan 注解类,重点,先获取加了@ComponentScan注解的配置类
        Set 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 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 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 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 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 doScan(String... basePackages) {
        Set beanDefinitions = new LinkedHashSet<>();
        for (String basePackage : basePackages) {
            // 找出当前包下面的所有符合条件的类,这个方法我们就不分析了。
            Set 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定义加载))