spring源码学习(一)

因为本人水平有限,本文内容较为简单,仅供我的学习笔记,或者你们参考,若是可以帮助你们,荣幸之至!本文主要分析AnnotationConfigApplicationContext实例化以后,到底干了那些事情。程序员

  • 首先经过实例化applicationContext

  

AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(Appconfig.class);

AnnotationConfigApplicationContext.getBean("beanName");

 

分析:第一句实例化annotationConfigApplicationContext,初始化了spring的环境,第二句就能够从spring ioc容器中获取bean。spring

  • 接下来查看构造方法
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
        this();
        register(annotatedClasses);
        refresh();
    }

 

  • 分析:this()方法会先调用父类的构造函数,再调用当前类的默认构造方法,在父类的构造方法当中,实例化了DefaultListableBeanFactory对象,spring当中的默认工厂, 在当前类的构造函数当中实例化了一个reader和scanner。
public GenericApplicationContext() {
        this.beanFactory = new DefaultListableBeanFactory();
    }
  • 这里的beanFactory很重要,后续实例化beanDefinition、beanName都存储在这里。
        this.reader = new AnnotatedBeanDefinitionReader(this);
        this.scanner = new ClassPathBeanDefinitionScanner(this);
  •  reader用来读取被加了注解的beanDenition,以及在当前的构造函数当中,会实例化spring当中很是重要的五个beanPostProcessor(后续分析),以及一个beanFactory,在本文最后会对其分析。
  • scanner顾名思义是用来扫描的,只不过是提供外部程序员来调用的,spring内部并无使用到。
public void register(Class<?>... annotatedClasses) {
        Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
        this.reader.register(annotatedClasses);
    }
  • 这里的register方法就是调用了咱们在构造函数当中初始化的reader,来完成注册beanDenifition。这里注册的类参数是一个数组,经过for循环来处理。注册一个bean以后须要调用refresh()方法,来完成实例化。若是注册了Appconfig类的话,若是不调用refresh()方法,项目会报错,若是注册的是普通的bean,在经过getBean来获取的时候,底层方法会手动调用refresh()当中的方法。接下来咱们看register()当中的方法。
<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);
    }
  • 分析:首先会判断是否跳过解析,若是元数据为null,或者没有加condition注解则返回false。由于该beanDenifition是初始化new出来的,因此元数据永远不会为空。接下来获取bean的做用域范围,默认是单例,生成beanName,接下来解析类的通用注解,好比说lazy,primary,description等等注解。处理限定符注解,还有自定义注解。beanDefinitionHolder主要是为了传值,在注册beanDenifition时候能够少传一个参数。这里传的这几个参数永远为null,好比@Nullable Supplier<T> instanceSupplier, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers,因此不用解析,若是咱们想要解析,只能获取到reader对象,手动调用传参数给他。
          // Still in startup registration phase
                this.beanDefinitionMap.put(beanName, beanDefinition);
                this.beanDefinitionNames.add(beanName);
                this.manualSingletonNames.remove(beanName);
  • map当中存储key:beanName,value:beanDefinition,beanDefinitionName集合当中存储全部的beanDenifitionName。
                // Register aliases for bean name, if any.
        String[] aliases = definitionHolder.getAliases();
        if (aliases != null) {
            for (String alias : aliases) {
                registry.registerAlias(beanName, alias);
            }
        }
  • 源码当中处理类的别名,spring当中若是设置了别名,能够经过id或者别名从spring容器当中获取类的实例。

接下来查看最后一个refresh方法,spring当中的bean生命周期,就是从这里开始的数组

@Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            prepareRefresh();

            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.

                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                initMessageSource();

                // Initialize event multicaster for this context.
                
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                onRefresh();

                // Check for listener beans and register them.
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                finishRefresh();
            }

            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }

                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();

                // Reset 'active' flag.
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }

            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }
    }

分析:ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();获取咱们的beanFactory,bean的生命周期就是从这里开始的,prepareBeanFactory顾名思义准备beanfactory,包括设置类加载器、解析器(解析相似与el表达式的页面语句,由spring提供的)、属性编辑器(spring boot当中的yml配置)、这里最重要的是添加了一个BeanPostProcessor,beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));来看这里作了什么事情!缓存

class ApplicationContextAwareProcessor implements BeanPostProcessor

该类继承自BeanPostProcessor,实现了这两个方法app

    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

缓存预热之时,咱们会使用@PostConstruct注解初始化init()方法,在构造函数以后执行,@preDestroy在销毁以后执行。后置处理器spring提供给咱们的扩展点,这两个方法会在init方法的先后执行,spring当中的AOP也是这样来完成对IOC的增强的,已经把bean暴漏出来了,在这里返回代理对象便可。接下来看ApplicationContextAwareProcessor实现后置处理器作了那些事情。编辑器

@Override
    @Nullable
    public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
        AccessControlContext acc = null;

        if (System.getSecurityManager() != null &&
                (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
                        bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
                        bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
            acc = this.applicationContext.getBeanFactory().getAccessControlContext();
        }

        if (acc != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareInterfaces(bean);
                return null;
            }, acc);
        }
        else {
            invokeAwareInterfaces(bean);
        }

        return bean;
    }

    private void invokeAwareInterfaces(Object bean) {
        if (bean instanceof Aware) {
            if (bean instanceof EnvironmentAware) {

                ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
            }
            if (bean instanceof EmbeddedValueResolverAware) {
                ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
            }
            if (bean instanceof ResourceLoaderAware) {
                ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
            }
            if (bean instanceof ApplicationEventPublisherAware) {
                ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
            }
            if (bean instanceof MessageSourceAware) {
                ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
            }
            if (bean instanceof ApplicationContextAware) {
                if (!bean.getClass().getSimpleName().equals("IndexDao"))
                ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
            }
        }
    }

分析:这里主要判断是否实现了ApplicationContextAware接口,若是实现了,就把applicationContext注入给他。此时就能够解释为何实现了applicationcontext接口,重写set方法,就能够获取applicationContext,解决单例模式下获取原型对象了。关于spring当中的其余后置处理器,会在后续文章中更新!ide

相关文章
相关标签/搜索