Spring源码跟踪,bean加载流程分析。

Posted 迪巴哥没八哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring源码跟踪,bean加载流程分析。相关的知识,希望对你有一定的参考价值。

这周末加班砍了一天假,利用周日的时间宅家撸了一次Spring加载流程,把加载步骤列了出来。
不才,还望大佬指教。

一.基于注解进入容器

@Test
   public void test03()
      AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
      UserService userService = context.getBean("userService", UserService.class);
      System.out.println(userService);
      userService.add();
   

二.核心的三个方法

 public AnnotationConfigApplicationContext(Class... componentClasses) 
        this();
        this.register(componentClasses);
        this.refresh();
    

三.this()方法

public AnnotationConfigApplicationContext() 
        this.reader = new AnnotatedBeanDefinitionReader(this);//读取器
        this.scanner = new ClassPathBeanDefinitionScanner(this);//扫包器
    

三- 一读取器的最重要的的方法:registerAnnotationConfigProcessors方法

3.1.创建工厂 DefaultListableBeanFactory

DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry)

作用:DefaultListableBeanFactory是整个bean加载的核心部分,是Spring注册机加载bean的默认实现

它继承了AbstractAutowireCapableBeanFactory类,并且实现了ConfigurableListableBeanFactory、Serializable、BeanDefinitionRegistry接口。

实现主要功能就是以list的方式操作bean,Spring拆分成这么多接口的原因对功能进行分工,各司其职,具体结构图如下所示,小伙伴们可以自己去看看源码,快捷键(选中类然后按ctrl+alt+u)。

3.2 设置比较器 AnnotationAwareOrderComparator

AnnotationAwareOrderComparator是OrderComparator的子类,用来支持Spring的Ordered类、@Order注解和@Priority注解。

3.3 设置解析器ContextAnnotationAutowireCandidateResolver

从下图继承关系图我们可以看到,ContextAnnotationAutowireCandidateResolver是子类,因此它的功能是最全最强大的。
SimpleAutowireCandidateResolver最简单的实现,适配器形式的存在,不可直接使用,
GenericTypeAwareAutowireCandidateResolver注入泛型依赖,
QualifierAnnotationAutowireCandidateResolver不仅仅能够处理@Qualifier注解,也能够处理通过@Value注解解析表达式得到的suggested value,ContextAnnotationAutowireCandidateResolver支持上述描述的功能,还支持@Lazy懒处理。

beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());//解析器

3.4:添加四个后置处理器:

ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、
CommonAnnotationBeanPostProcessor 、EventListenerMethodProcessor。

ConfigurationClassPostProcessor:配置类后置处理器,负责扫描有@Configuration的注解

AutowiredAnnotationBeanPostProcessor:自动注入后置处理器。

CommonAnnotationBeanPostProcessor :负责解析@Resource、@WebServiceRef、@EJB三个注解。
EventListenerMethodProcessor:对 @EventListener 提供支持.主要是标注了 @EventListener 的方法进行解析, 然后转换为一个 ApplicationListener.

至此读取器AnnotatedBeanDefinitionReader执行完毕,
其底层方法registerAnnotationConfigProcessors对应的代码提供如下。

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) 
        DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);//1.创建工厂对象
        if (beanFactory != null) 
            if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) 
                beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);//2.设置比较器
            
            if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) 
                beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());//
            
        
        Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet(8);
        RootBeanDefinition def;
        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"));
        
        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"));
        
        if (jsr250Present && !registry.containsBeanDefinition("org.springframework.context.annotation.internalCommonAnnotationProcessor")) 
            def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);//负责解析@Resource、@WebServiceRef、@EJB三个注解。
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalCommonAnnotationProcessor"));
        
        if (jpaPresent && !registry.containsBeanDefinition("org.springframework.context.annotation.internalPersistenceAnnotationProcessor")) 
            def = new RootBeanDefinition();
            try 
                def.setBeanClass(ClassUtils.forName("org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor", AnnotationConfigUtils.class.getClassLoader()));
             catch (ClassNotFoundException var6) 
                throw new IllegalStateException("Cannot load optional framework class: org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor", var6);
            
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalPersistenceAnnotationProcessor"));
        
        if (!registry.containsBeanDefinition("org.springframework.context.event.internalEventListenerProcessor")) 
            def = new RootBeanDefinition(EventListenerMethodProcessor.class);//对 @EventListener 提供支持.
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.event.internalEventListenerProcessor"));
        
        if (!registry.containsBeanDefinition("org.springframework.context.event.internalEventListenerFactory")) 
            def = new RootBeanDefinition(DefaultEventListenerFactory.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.event.internalEventListenerFactory"));
        
        return beanDefs;
    

三-二: ClassPathBeanDefinitionScanner底层方法:ClassPathBeanDefinitionScanner。

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment, @Nullable ResourceLoader resourceLoader) 
        this.beanDefinitionDefaults = new BeanDefinitionDefaults();
        this.beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;
        this.scopeMetadataResolver = new AnnotationScopeMetadataResolver();
        this.includeAnnotationConfig = true;
        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        this.registry = registry;
        if (useDefaultFilters) 
            this.registerDefaultFilters();
        
        this.setEnvironment(environment);
        this.setResourceLoader(resourceLoader);
    

this.registerDefaultFilters: 注册默认的过滤器
this.setEnvironment: 设置环境
this.setResourceLoader:设置类加载器

至此this()方法执行完毕,我们接下来看register与refresh方法。

四、register:

public void register(Class... componentClasses) 
        Class[] var2 = componentClasses;
        int var3 = componentClasses.length;
        for(int var4 = 0; var4 < var3; ++var4) 
            Class<?> componentClass = var2[var4];
            this.registerBean(componentClass);
        
    

遍历类然后注册,我们接下来看看核心方法registerBean下的doRegisterBean方法。

 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);
        if (!this.conditionEvaluator.shouldSkip(abd.getMetadata())) 
            abd.setInstanceSupplier(supplier);
            ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
            abd.setScope(scopeMetadata.getScopeName());
            String beanName = name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry);
            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];
                    if (Primary.class == qualifier) 
                        abd.setPrimary(true);
                     else if (Lazy.class == qualifier) 
                        abd.setLazyInit(true);
                     else 
                        abd.addQualifier(new AutowireCandidateQualifier(qualifier));
                    
                
            
            if (customizers != null) 
                BeanDefinitionCustomizer[] var13 = customizers;
                var10 = customizers.length;
                for(var11 = 0; var11 < var10; ++var11) 
                    BeanDefinitionCustomizer customizer = var13[var11];
                    customizer.customize(abd);
                
            
            BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
            definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
            BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
        
    

解析用户传入的 Spring 配置类,解析成一个 BeanDefinition 然后注册到容器中。

五、最重要的方法refresh方法。

public void refresh() throws BeansException, IllegalStateException 
        Object var1 = this.startupShutdownMonitor;
        synchronized(this.startupShutdownMonitor) 
            this.prepareRefresh();//1、刷新前准备
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);//2、准备bean工厂
            try 
                this.postProcessBeanFactory(beanFactory);//3、空方法
                this.invokeBeanFactoryPostProcessors(beanFactory);//
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                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();
            
        
    

1:this.prepareRefresh()

作用记录初始化的时间,初始化资源,运行环境配置,创建监听器集合。

protected void prepareRefresh() 
        this.startupDate = System.currentTimeMillis();//1.记录初始化的时间
        // 切换容器为初始化状态
        this.closed.set(false);
        this.active.set(true);
        //确保日志开启
        if (this.logger.isDebugEnabled()) 
            if (this.logger.isTraceEnabled()) 
                this.logger.trace("Refreshing " + this);
             else 
                this.logger.debug("Refreshing " + this.getDisplayName());
            
        
        //初始化资源(为空方法,可以给子类扩展。)
        this.initPropertySources();
        //运行环境配置
        this.getEnvironment().validateRequiredProperties();
        //创建监听器集合,保存监听器。
        if (this.earlyApplicationListeners == null) 
            this.earlyApplicationListeners = new LinkedHashSet(this.applicationListeners);
         else 
            this.applicationListeners.clear();
            this.applicationListeners.addAll(this.earlyApplicationListeners);
        
        this.earlyApplicationEvents = new LinkedHashSet();
    

2:prepareBeanFactory()

作用: 设置bean的加载器,设置El表达式解析器,属性注册解析器、Bean后置处理器等。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) 
        //1.设置Bean的加载器
        beanFactory.setBeanClassLoader(this.getClassLoader());
        //2.设置EL表达式解析器
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        //3.设置属性注册解析器 
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
        //4.设置Bean后置处理器
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        //5.设置自动忽略的装配接口
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
        beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
        //6.注册可以解析的自动装配
        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));
        //7.判断是否有loadTimeWeaver的bean,如果有则交给LoadTimeWeaverAwareProcessor。
        if (beanFactory.containsBean("loadTimeWeaver")) 
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactorySpring源码跟踪,bean加载流程分析。

Spring源码分析非懒加载的Bean实例化过程(下篇)

Spring源码分析

Spring源码分析配置文件读取流程

Spring源码分析配置文件读取流程

Spring源码分析Bean加载流程概览