spring5之容器始末源码赏析 (一)总览

     首先,本系列并非以介绍spring5 的新特性为主,之因此以spring5为标题,是由于即将赏析的源码来自最新的spring版本.虽然说是spring最新版本,可是容器的整个生命周期与以前版本相比,并无很大的变化,咱们主要来看spring是如何一步步构建本身的容器,一步步将混乱不堪,错综复杂的依赖关系管理的层次分明,一步步组建本身的spring帝国.web

    由于篇幅缘由,并不能在一篇博客中将全部spring容器的内容都介绍完成,所以,将分为几个部分分别介绍,本篇会先从最顶层浏览一下spring的一些容器,以及spring抽象出的容器的组装过程,使咱们对spring容器有一个总体上的认知.spring

  先来介绍spring中几个重要的接口的做用:springboot

1.BeanFactory

2.BeanDefinition

3.BeanDefinitionRegistry

4.ApplicationContext


先看BeanFactory,这个接口定义了全部beanfactory基础功能: 根据名称获取bean,获取bean的类型/别名,判断bean是否存在等,能够看到,全部实现了这个接口的类,都具有这个功能.

BeanDefinition,定义了容器管理的对象.这个接口是整个spring的核心.BeanDefinition能够看作spring的领域模型,它是对全部bean统一建模的产物,涵盖了bean的全部信息,全部注册进spring容器的bean均会被处理成各类beanDefinition的实现
存储起来.

BeanDefinitionRegistry定义了beanDefinition的注册功能.实现了这个接口的类,具有了注册beandefinition的能力,将组装好的beandefinition注册到容器中。


最后看ApplicationContext,这个是容器的接口,全部容器均实现了这个接口,它定义了容器的基本功能:获取容器名,获取父容器,获取beanfactory,注册bean,等等,来看一下继承关系:

 咱们发现它继承许多接口,这意味着实现这个接口的类,必须具有它所实现的全部类的功能,固然,这些功能正真实现的地方不会在application的实例中,这里用到了代理模式(百度),将主要职责委托给其它实现接口的类去作,将调用者和实现者解耦,使代码具有良好的扩展性。架构

spring的容器有多种,我把它分两大类:应用类和web类。app

应用类中经常使用的几个容器:函数

AnnotationConfigApplicationContext  (主要是注解驱动,spring3.0之后加入)
GenericXmlApplicationContext   (也是3.0之后加入的,能够做为下面两种的替代。相对与相面两个容器来讲比较灵活,能够灵活设置xml)
ClassPathXmlApplicationContext  (和下面的容器基本同样,一个是类路径加载(主要特点是能加载jar中的xml文件),一个是文件路径加载。二者实现基本同样,因此会有GenericXmlApplicationContext的出现)
FileSystemXmlApplicationContext
web类的经常使用容器:
基本与上面一一对应,这里就简单列举一些:
AnnotationConfigWebApplicationContext
GenericWebApplicationContext
XmlWebApplicationContext

了解上面的基本概念之后,咱们就要开始spring容器的探索之旅了,由于考虑到web容器还要考虑servlet版本,以及web.xml的配置,相对于应用容器来讲稍微复杂一些。因此此次咱们并不会以支持web容器为例去分析。
最近,springboot比较火爆(默认配置就是使用AnnotationConfigApplicationContext容器),咱们就来看看AnnotationConfigApplicationContext这个容器,看它是如何把一个个注解都转化为本身认识的bean并管理起来,
并为咱们提供各类各样的服务。(其实几个容器的底层实现都同样,毕竟是同一个爸生的。。。)
先看一个简单的栗子:

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(Level1Config.class);
context.refresh();
Level2Component l = (Level3Component) context.getBean("level2Component");
l.asd();
@Configuration
@ComponentScan("org.springframework.context.annotation.componentscan.level2")
public class Level1Config {
    @Bean
    public TestBean level1Bean() {
        return new TestBean("level1Bean");
    }
}
@Component
public class Level2Component {
    @Autowired
    SimpleComponent simpleComponent;
    public void asd(){
        simpleComponent.testq();
    }

}
@Component
public class SimpleComponent {

    public void testq(){
        System.out.println("asdf");
    }

    @Bean
    public String exampleBean() {
        return "example";
    }

}

这个栗子中,spring扫描了“org.springframework.context.annotation.componentscan.level2”包,装载了里面的Level2Component和SimpleComponent等,并将SimpleComponent实例化赋值给Level2Component,而后咱们就能够经过context获取到Level2Component的实例,并调用SimpleComponent的方法。工具

咱们看到从context的声明到bean实例被调用,只通过了4行代码,可谓简单至极,但在这背后却作了咱们想象不到的许多事。ui

在深刻源码以前,咱们最好先从最顶层看一下它的架构,而后带着问题去看,这样才能有目的性的找到答案和学到东西,废话很少说,先看一下spring是如何装配AnnotationConfigApplicationContext的,我的总结以下:this

准备 ——>初始化容器——>扫描装配beanDefinition(这里只是初步装配)——>组装实例化beanlua

所以,本系列也会分红四部分和你们一块儿来鉴赏各个流程的代码。

这里就先来介绍相对简单的一步:准备。

准备阶段,spring主要是为容器初始化一些bean,将一些配置文件读取,扫描器,beanfacotry,bean的一些默认处理工具类实例化并装配起来,看一下构造函数:

    public AnnotationConfigApplicationContext() {
        this.reader = new AnnotatedBeanDefinitionReader(this);
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }

还有它父类的构造函数:

    public GenericApplicationContext() {
        this.beanFactory = new DefaultListableBeanFactory();
    }
public AbstractApplicationContext() {
        this.resourcePatternResolver = getResourcePatternResolver();
    }

按照类初始化的顺序,咱们能够看到,这里初始化了resourcePatternResolver,beanfactory,annotationBeanDefinitionReader,classPathBeanDefinitionScanner,这几个类,这些类的做用分别是:资源定位解析,定义bean容器,注解类解析,类路径资源扫描。它们的详细实如今后续讨论中依然会出现,这里咱们只详细关注AnnotationBeanDefinitionReader,这个类,由于这个类参与了准备阶段的工做。

先看一下构造函数:

    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
        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, null);
        AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
    }
ConditionEvaluator是@Conditional注解的解析的实现类,这里咱们重点看

AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);

    public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
            BeanDefinitionRegistry registry, @Nullable Object source) {

        DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
        if (beanFactory != null) {
            if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
                beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
            }
            if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
                beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
            }
        }

        Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(4);

        if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
        if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
        if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition();
            try {
                def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
                        AnnotationConfigUtils.class.getClassLoader()));
            }
            catch (ClassNotFoundException ex) {
                throw new IllegalStateException(
                        "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
            }
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
        }
        if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
        }

        return beanDefs;
    }

在AnnotatedBeanDefinitionReader被实例化的时候spring洋洋洒洒注册了一堆bean,这些bean将在之后咱们有新的bean加入的时候起关键性做用,好比改变bean的行为,好比监听发布事件,好比解析一个外部定义的配置类,等等,这些bean在后面的分析中均会一一出现,这里一样不作全面介绍,咱们只要知道,这些bean实在这个时候就已经被spring装载进来了。

咱们继续往下看:

接着就是注册咱们自定义的bean了.
public void register(Class<?>... annotatedClasses) {
        Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
        this.reader.register(annotatedClasses);
    }

在咱们register配置类的时候reader(即AnnotationBeanDefinitionReader)的register方法会被调用,进而会调用它的doRegisterBean方法,将配置类注入容器中:

<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
            @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {

        AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
        if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
            return;
        }

        abd.setInstanceSupplier(instanceSupplier);
        ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
        abd.setScope(scopeMetadata.getScopeName());
        String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

        AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
        if (qualifiers != null) {
            for (Class<? extends Annotation> qualifier : qualifiers) {
                if (Primary.class == qualifier) {
                    abd.setPrimary(true);
                }
                else if (Lazy.class == qualifier) {
                    abd.setLazyInit(true);
                }
                else {
                    abd.addQualifier(new AutowireCandidateQualifier(qualifier));
                }
            }
        }
        for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
            customizer.customize(abd);
        }

        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
        definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
        BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
    }

按照顺序,首先咱们能够看到,配置类会被放到AnnotatedGenericBeanDefinition中:

public AnnotatedGenericBeanDefinition(Class<?> beanClass) {
        setBeanClass(beanClass);
        this.metadata = new StandardAnnotationMetadata(beanClass, true);
    }

  annotationGenericBeanDefinition实例会持有StandardAnnotationMetadata的实例,StandardAnnotationMetadata顾名思义,它是封装了这个类的注解的元数据。接着,spring会判断是否符合Condition注解的条件(spring4的加进来的一个注解),接下来会解析scope注解,来肯定这个bean的做用域,接下来会调用processCommonDefinitionAnnotations方法处理一些常规的注解:@Primary,@DependsOn,@Rule.@Description,并将这些信息放入定义好的beanDefinition中,接着经过BeanDefinitionReaderUtils将beanDefinition注册到容器里。至此算是容器中的第一个咱们本身的bean就注册完成。

  咱们看到,register方法实际上就是将配置类中一些咱们不长用注解信息解析并放入beandefinition中,将注解元数据放入StandardAnnotationMetadata中,由beanDefinition持有,最终把beanDefinition放入容器中(beanFactory),并无发生什么不得了的事情,咱们定义的注解类也只是初步解析,并无进行扫描或者注入其它bean,事实上,在bean的准备阶段,spring确实没作多少事情,而是将一些十分重要的bean一一初始化进容器中,而咱们自定义的配置类就是其中之一。

 

好了,第一阶段就到这里。第一阶段准备阶段,spring实例化了一个reader,并在实例化过程当中装载了annotationConfigApplicationContext容器特有的bean的处理逻辑,随后把咱们的配置类也装载进去变完成了准备阶段的工做。

 

                                                                                                                                                    转载请注明出处。

相关文章
相关标签/搜索