Spring源码系列(一)——容器的创建

一、容器的创建

下面从Spring容器的创建开始分析,逐步深入来探究Spring的源码。

入口函数:

public static void main(String[] args) {
    // 创建容器
    AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

    // 从容器中获取Bean
    IndexDao dao = annotationConfigApplicationContext.getBean(IndexDao.class);

    // 调用Bean的方法
    dao.query();
}

这里要看一下AnnotationConfigApplicationContext这个类的构造方法:

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
    // 这里由于它有父类构造方法,故而先调用父类的构造方法,然后才会调用自己的构造方法
    this();
    register(annotatedClasses);
    refresh();
}

因为需要调用父类的构造方法,所以看下AnnotationConfigApplicationContext继承结构:

在这里插入图片描述

查看GenericApplicationContext类,并查看其构造方法:

public GenericApplicationContext() {
    // 创建一个DefaultListableBeanFactory工厂
    this.beanFactory = new DefaultListableBeanFactory();
}

注:对于这个DefaultListableBeanFactory,我们就可以把它当成一个Spring容器

下面要看一下AnnotationConfigApplicationContext无参构造方法了,因为上面的构造方法中调用了this()方法。

public AnnotationConfigApplicationContext() {
    // 创建一个 AnnotatedBeanDefinitionReader读取器,
    // 同时向容器中填加了6个Spring的后置处理器:BeanFactoryPostProcessor、BeanPostProcessor
    this.reader = new AnnotatedBeanDefinitionReader(this);

    // 可以用来扫描包或者类,继而转换成BeanDefinition,但实际上我们扫描包工作不是这个scanner对象来完成的
    // 是spring自己new的一个ClassPathBeanDefinitionScanner
    // 这里的scanner仅仅是为了能够让程序员在外部调用AnnotationConfigApplicationContext对象的scan方法
    this.scanner = new ClassPathBeanDefinitionScanner(this);
}

这个无参的构造方法,初始化一个bean的读取器和扫描器。

从这地方可以看出,我们的入口程序可以换一种写法,代码如下:

public static void main(String[] args) {
    
    AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
    
    annotationConfigApplicationContext.register(AppConfig.class);
    annotationConfigApplicationContext.refresh();
    
    IndexDao dao = annotationConfigApplicationContext.getBean(IndexDao.class);
    dao.query();
}

以上代码能看懂么?其实就是把带参数的构造函数中的两行代码提取出来了,直接调用了AnnotationConfigApplicationContext无参构造函数。

二、读取器创建

读取器和扫描器创建的入口在AnnotationConfigApplicationContext无参构造方法中,来看下面的代码:

this.reader = new AnnotatedBeanDefinitionReader(this);

注:此处的this为AnnotationConfigApplicationContext,表示一个Registry

进入到AnnotatedBeanDefinitionReader的构造函数中:

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
    // 调用两个参数的构造器,如下
    this(registry, getOrCreateEnvironment(registry));
}

// 两个参数的构造器
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, 
                                     Environment environment) {
    this.registry = registry;
    this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
    // 这地方很重要(☆☆☆☆☆)
    AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

下面来看下AnnotationConfigUtils这个类的registerAnnotationConfigProcessors()方法:

public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
   // 下面
   registerAnnotationConfigProcessors(registry, null);
}

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

    // 这行就是验证传进来的registry是不是DefaultListableBeanFactory类型,第一部分已说明,是!!
    DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);

    if (beanFactory != null) {
        if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
            // AnnotationAwareOrderComparator主要能解析@Order注解和@Priority
            beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
        }
        if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
            // ContextAnnotationAutowireCandidateResolver提供处理延迟加载的功能
            beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
        }
    }

    Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
    
    //BeanDefinitio的注册,这里很重要,需要理解注册每个bean的类型
    // 1、org.springframework.context.annotation.internalConfigurationAnnotationProcessor
    if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        // 向registry中放入ConfigurationClassPostProcessor
        RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
        def.setSource(source);
        // 往Set集合中加入ConfigurationClassPostProcessor
        beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // 2、org.springframework.context.annotation.internalAutowiredAnnotationProcessor
    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));
    }

    // 3、org.springframework.context.annotation.internalRequiredAnnotationProcessor
    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));
    }

    // 4、org.springframework.context.annotation.internalCommonAnnotationProcessor
    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));
    }

    // 5、org.springframework.context.annotation.internalPersistenceAnnotationProcessor
    if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition();
            		  def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
                                    AnnotationConfigUtils.class.getClassLoader()));
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // 6、org.springframework.context.event.internalEventListenerProcessor
    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));
    }

    // 7、org.springframework.context.event.internalEventListenerFactory
    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;
}

在上面的代码中,创建了一个大小为8的Set集合,集合元素类型为:BeanDefinitionHolder

并把下面7个类定义成BeanDefinitionHolder后添加到Set中,并返回。

  • ConfigurationClassPostProcessor.class

  • AutowiredAnnotationBeanPostProcessor.class

  • RequiredAnnotationBeanPostProcessor.class

  • CommonAnnotationBeanPostProcessor.class(Bean生命周期回调方法)

  • PersistenceAnnotationBeanPostProcessor.class

  • EventListenerMethodProcessor.class

  • DefaultEventListenerFactory.class

下图是debug断点后,看到的Set集合中的内容为6个,其中,PersistenceAnnotationBeanPostProcessor.class这个类不符合要求,没有被添加。

这6个类要么是BeanFactoryPostProcessor的实现,要么是BeanPostProcessor的实现。

在这里插入图片描述
在这里插入图片描述

上面的代码需要注意一下下面这行代码,下面来介绍一下这个registerPostProcessor()方法

beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));

AnnotationConfigUtils.registerPostProcessor()方法如下:

private static BeanDefinitionHolder registerPostProcessor(BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
    definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    // 向registry中注册BeanDefinition
    registry.registerBeanDefinition(beanName, definition);
    return new BeanDefinitionHolder(definition, beanName);
}

其实搞清楚这个方法,就是要搞清楚BeanDefinitionRegistryBeanDefinitionHolder是干嘛的。

BeanDefinitionRegistry是个接口,里面定义了一些操作BeanDefinition的方法,如下:

public interface BeanDefinitionRegistry extends AliasRegistry {

	void registerBeanDefinition(String beanName, BeanDefinition beanDefinition);

	void removeBeanDefinition(String beanName);

	BeanDefinition getBeanDefinition(String beanName) ;

	boolean containsBeanDefinition(String beanName);

	String[] getBeanDefinitionNames();

	int getBeanDefinitionCount();

	boolean isBeanNameInUse(String beanName);
}

而这些方法的主要实现类如下,是不是有看到了熟悉的DefaultListableBeanFactory

在这里插入图片描述

下面要来看下DefaultListableBeanFactory中的registerBeanDefinition()

其实Spring容器,底层就是一个ConcurrentHashMap

// 存放所有BeanDefinition的Map
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

// 存放了所有BeanDefinition的名字,通过扫描进去的
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);

@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
    throws BeanDefinitionStoreException {

    // 先从beanDefinitionMap中,根据beanName去获取BeanDefinition
    BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
    
    if (existingDefinition != null) {
        this.beanDefinitionMap.put(beanName, beanDefinition);
    } else {
        if (hasBeanCreationStarted()) {
            synchronized (this.beanDefinitionMap) {
                this.beanDefinitionMap.put(beanName, beanDefinition);
                List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
                updatedDefinitions.addAll(this.beanDefinitionNames);
                updatedDefinitions.add(beanName);
                this.beanDefinitionNames = updatedDefinitions;
                if (this.manualSingletonNames.contains(beanName)) {
                    Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
                    updatedSingletons.remove(beanName);
                    this.manualSingletonNames = updatedSingletons;
                }
            }
        } else {
            // Still in startup registration phase
            this.beanDefinitionMap.put(beanName, beanDefinition);
            this.beanDefinitionNames.add(beanName);
            this.manualSingletonNames.remove(beanName);
        }
        this.frozenBeanDefinitionNames = null;
    }

    if (existingDefinition != null || containsSingleton(beanName)) {
        resetBeanDefinition(beanName);
    } else if (isConfigurationFrozen()) {
        clearByTypeCache();
    }
}

BeanDefinitionHolder类如下,就是对BeanDefinition进行了再次封装。

public class BeanDefinitionHolder implements BeanMetadataElement {

	private final BeanDefinition beanDefinition;

	private final String beanName;
    
    //…… 略
}

下面打一个断点在registerAnnotationConfigProcessors()方法的return beanDefs;语句,看下面两个集合中的内容。

beanDefinitionNames是个 List。

在这里插入图片描述

beanDefinitionMap是个Map。

在这里插入图片描述

到此处,读取器的创建就结束了。回想一下,到目前为止,做了哪些工作?

只是向Spring容器中添加了6个BeanDefinition,需要注意的是:这6个BeanDefinition是Spring 自己添加的,这6个BeanDefinition的功能是什么呢???Spring不会平白无故的往容器中放多余的东西吧。

这里,只是完成了Class类到BeanDefinition的转变,但BeanDefinition并没有实例化。

所以,这6个BeanDefinition很重要,后面会讲解它们的作用。

三、扫描器创建

从上文可以知道,扫描器创建的入口也在AnnotationConfigApplicationContext无参构造函数中,来看下面的代码:

this.scanner = new ClassPathBeanDefinitionScanner(this);

这地方创建了一个ClassPathBeanDefinitionScanner扫描器对象,通过层层的构造函数封装,调用到了下面的这个构造函数。这地方代码不重要,可以直接忽略。

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
							Environment environment, @Nullable ResourceLoader resourceLoader) {

    this.registry = registry;

    if (useDefaultFilters) {
        registerDefaultFilters();
    }
    setEnvironment(environment);
    setResourceLoader(resourceLoader);
}

对于这个这个ClassPathBeanDefinitionScanner扫描器,只需要知道下面的内容:

这个扫描器可以用来扫描包或者类,继而将扫描到的类转换成BeanDefinition,但是实际上我们扫描包工作不是这个scanner对象来完成的!!!而是Spring自己new的一个ClassPathBeanDefinitionScanner,后面的代码分析会讲到。

这里的scanner仅仅是为了程序员能够在外部调用AnnotationConfigApplicationContext对象的scan方法。

四、小结

到目前为止,Spring做了以下几部分工作:

  • 创建了一个DefaultListableBeanFactory容器
  • 创建一个AnnotatedBeanDefinitionReader读取器
    • 在创建读取器的过程中,向Spring容器中添加了6个Spring自己的BeanDefinition
  • 创建一个ClassPathBeanDefinitionScanner扫描器
    • 这个扫描器仅仅是为了让程序员能够在外部调用,Spring真正的扫描工作不是这个扫描器来完成的

五、补充

1.BeanPostProcessor

BeanPostProcessor是Spring框架提供的一个扩展类点,但Spring的扩展类点不止这一个。

通过实现BeanPostProcessor接口,程序员就可插手Spring Bean实例化的过程,在Bean实例化之后、初始化之前执行,从而减轻了BeanFactory的负担,值得说明的是这个接口可以设置多个,会形成一个列表,然后依次执行。

程序员自己定义的BeanPostProcessor,只需要实现BeanPostProcessor接口,然后加上@Component注解,就可以自动被扫描并添加到Spring容器中,但是Spring框架默认的怎么办呢?

本文第二部分,在读取器创建的时候,Spring框架就默认创建了5个BeanPostProcessor。这5个BeanPostProcessor非常重要。

比如AOP就是在Bean实例后期间将切面逻辑织入Bean实例中的,AOP也正是通过BeanPostProcessor和Spring容器建立起了联系。

下面看看Spring提供哪些默认的BeanPostProcessor实现,前方高能!!!

因为高能,故而只是解释几个常用的:

  • ApplicationContextAwareProcessor,简写acap
    作用:当应用程序定义的Bean实现ApplicationContextAware接口时注入ApplicationContext对象

  • InitDestroyAnnotationBeanPostProcessor

    作用: 用来处理自定义的初始化方法和销毁方法。

    Spring中提供了3种自定义初始化和销毁方法分别是

    • 通过@Bean指定init-method和destroy-method属性

    • Bean实现InitializingBean接口和实现DisposableBean

    • @PostConstruct、@PreDestroy

    为什么spring通这三种方法都能完成对bean生命周期的回调呢?

    可以通过InitDestroyAnnotationBeanPostProcessor的源码来解释

  • InstantiationAwareBeanPostProcessor

  • CommonAnnotationBeanPostProcessor

  • AutowiredAnnotationBeanPostProcessor

  • RequiredAnnotationBeanPostProcessor

  • BeanValidationPostProcessor

  • AbstractAutoProxyCreator

2.Spring容器中属性说明

BeanDefinition:简称bd,是对一个Bean的描述。类比,在Java中,你要描述一个用户,你得定义一个User类,在Spring中,你要描述一个Bean的话,就定义个BeanDefinition

beanDefinitionNames:存在Bean的名字

beanDefinitionMap:存放Bean的名字与BeanDefinition的对应关系

AnnotatedBeanDefinitionReader

BeanDefinitionRegistry:简称bdr,把一个BeanDefinition放入到beanDefinitionMap中。

  • 8
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

止步前行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值