spring源码分析(一)

你怎么理解Spring

IOC、AOP,体现在Spring FrameWork中

spring源码分析(一)_第1张图片
spring源码分析(一)_第2张图片

只实现IOC功能的花不用导入core依赖,context就行

idea打开的源码都是反编译过的,同时做一个优化,但是只是只读文件,不能操作修改

spring源码分析(一)_第3张图片

虽然我们只依赖context,maven帮我们把aop、jcl、beans、core等都下下来了

spring源码分析(一)_第4张图片

使用idea和gradle编译spring5源码

spring用gradel开发,

build成功后

新建module

spring源码分析(一)_第5张图片
spring源码分析(一)_第6张图片
spring源码分析(一)_第7张图片
spring源码分析(一)_第8张图片

新建一个测试类

package com.suntong.test;

import com.suntong.app.Appconfig;
import com.suntong.service.CityService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;


public class Test {
    
    /*
    * 
    * 把类扫描出来 - 扫描出来干什么
    * 把bean实例化
    * */

    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext =
                new AnnotationConfigApplicationContext(Appconfig.class);
        System.out.println(annotationConfigApplicationContext.getBean(CityService.class));
    }
    
}

点开AnnotationConfigApplicationContext实现

public AnnotationConfigApplicationContext(Class... componentClasses) {
//有父类,先调用父类的构造方法,然后调用自己的构造方法
//在自己的构造方法中初始一个读取器和扫描器
        this();
        register(componentClasses);
        refresh();
    }

注解配置spring环境

ps:ClassPathXmlApplicationContext 通过xml配置初始化spring环境

无参构造方法

public AnnotationConfigApplicationContext() {
        /*
        * 父类的构造方法
        * 创建一个读取注解等我Bean定义读取器
        * 什么是bean定义? BeanDefinition
        * */
        this.reader = new AnnotatedBeanDefinitionReader(this);
        
        /*
        * 可以用来扫描包或类,进而转换成bd
        * 但是实际上扫描包工作不是scanner这个对象完成的
        * 是spring自己new的一个ClassPathBeanDefinitionScanner
        * 这里的scanner仅仅是为了程序员能够在外部调用AnnotationConfigApplicationContext
        * */
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }

但是,该类继承父类,调用父类的无参构造函数

public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {

点进去GenericApplicationContext

//核心,spring工厂
public GenericApplicationContext() {
        this.beanFactory = new DefaultListableBeanFactory();
    }

DefaultListableBeanFactory类继承关系复杂,可以理解为其为spring工厂

回到AnnotationConfigApplicationContext类

public AnnotationConfigApplicationContext(Class... componentClasses) {
        //有父类,先调用父类的构造方法,然后调用自己的构造方法
        //在自己的构造方法中初始一个读取器和扫描器
        //beanFactory
        this();
        
        //ac.register(AppConfig.class)
        //this.beanDefinitionMap.put(beanName,beanDefinition);
        register(componentClasses);
        
        //SpringFramework最重要的方法
        refresh();
    }

点开refresh方法,里面调用了12个方法

@Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            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.
                //重要方法 完成了把类扫描出来 处理各种 import,如 @ImportResource("xxx.xml")
                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.
                //new 一个扫描对象 单例
                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();
            }
        }
    }

spring环境:spring所有组件一起工作保持spring正常运行叫做spring环境,组件如BeanDefinition(用来描述类,描述springbean,因为正常的类存不下那么多信息) , Map , 单例池

扫描:
找到符合规则的类
for循环的到它们的信息,如是否为抽象类,是否为单例,描述等等
最后将其放在map中

调用了invoke方法后扫描之后会实现BeanFactoryPostProcessor接口的实现类

@FunctionalInterface
public interface BeanFactoryPostProcessor {

    /**
     * Modify the application context's internal bean factory after its standard
     * initialization. All bean definitions will have been loaded, but no beans
     * will have been instantiated yet. This allows for overriding or adding
     * properties even to eager-initializing beans.
     * @param beanFactory the bean factory used by the application context
     * @throws org.springframework.beans.BeansException in case of errors
     */
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

这个实现类我们可以自己提供

ctrl + alt + b 看实现类

spring beanFactory和factoryBean有什么区别

factoryBean是特殊bean,去实现一个接口

factoryBean 和 普通bean有什么区别

spring容器是BeanDefinition、BeanFactoryPostProcessor、BeanFactory、BeanDefinition Map以及singletonObjects
单例池concurrentmap

循环依赖:A依赖B,B依赖A
Spring先把B创建出来,new出来时不能把B称之为bean,只是一个对象(bean有完整的spring生命周期,如还要加AOP,lifeclycallback生命周期回调方法,自动注入;)

getSingleton(beanName)方法,第一次get发现A是空,判断原型、判断父子、判断依赖,可以了就记录为正在创建当中,然后就会new B去,然后就是第二次new A的过程,因为B依赖于A,这次get发现A在创建过程中,表示A已经成为了一个对象,就不从单例池中去拿,这样B就创建成功了(涉及到自动装配等很多东西)

bean单例支持,原型不支持循环依赖,可以用lookup函数

spring后置处理器BeanPostProcessor是分功能的,所有后置处理器都继承了这个处理器

你可能感兴趣的:(spring源码分析(一))