Spring源码系列:核心概念解析

科技资讯 投稿 7800 0 评论

Spring源码系列:核心概念解析

前言

BeanDefinition

BeanDefinition是Spring框架中的一个重要概念,它定义了一个Bean的基本属性和行为,比如:

    BeanClassName,当前的bean名字
  1. Scope,是否单例,具体枚举:#SCOPE_SINGLETON、#SCOPE_PROTOTYPE
  2. LazyInit,是否懒加载,默认不是
  3. DependsOn,是否依赖其他bean,如果依赖,则会先创建依赖bean
  4. InitMethodName,初始化方法名称
  5. DestroyMethodName,销毁类方法名称
  6. ......还有更多,但是这几个大体已经差不多了
    < bean/>
  1. @Bean
  2. @Component(@Controller、@Service

这些都是被称为申明式定义Bean。就是使用Spring提供好的封装。

    // 创建一个Spring容器
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class;

        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(.getBeanDefinition(;
        beanDefinition.setBeanClass(UserService.class;
        //当然还可以设置其他上面我说的其他属性:懒加载什么的
        applicationContext.registerBeanDefinition("userService", beanDefinition;

        UserService userService = (UserService applicationContext.getBean("userService";
        userService.test(;

无论是通过注解方式还是编程方式来定义Bean,最终都是需要使用BeanDefinition来描述Bean的基本属性和行为,然后将其放入Spring容器中进行管理。

BeanDefinitionReader

BeanDefinitionReader的核心方法包括以下几个:

    BeanDefinitionRegistry,用来注册bean定义,相当于一个工厂
  1. BeanNameGenerator,用来生成bean名字的生成器
  2. loadBeanDefinitions,从资源中加载bean

XmlBeanDefinitionReader

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class;
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(context;
//加载xml中配置的所有<bean>
int i = xmlBeanDefinitionReader.loadBeanDefinitions("spring.xml";
System.out.println(context.getBean("userService"

AnnotatedBeanDefinitionReader

细心的朋友,应该可以发现AnnotatedBeanDefinitionReader是一个单独的类,不是BeanDefinitionReader的子类,但它的方法与BeanDefinitionReader基本相同,官方说是方便的适配器,用于编程注册bean类,他可以解析@Conditional,@Scope、@Lazy、@Primary、@DependsOn、@Role、@Description相关注解,具体操作如下:

// 创建一个Spring容器
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class;

//        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(.getBeanDefinition(;
//        beanDefinition.setBeanClass(UserService.class;
//        applicationContext.registerBeanDefinition("userService", beanDefinition;

        new AnnotatedBeanDefinitionReader(applicationContext.registerBean(UserService.class;

        UserService userService = (UserService applicationContext.getBean("userService";
        userService.test(;

同样的,他也可以让我们注册的bean走完创建的整个生命周期过程。

ClassPathBeanDefinitionScanner

使用ClassPathBeanDefinitionScanner的步骤如下:

// 创建一个Spring容器  
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class;  
  
new ClassPathBeanDefinitionScanner(applicationContext.scan("com.xiaoyu";  
UserService userService = (UserService applicationContext.getBean("userService";  
userService.test(;

BeanFactory

BeanFactory是Spring框架中的一个重要接口,他就是Spring用于管理Bean对象的创建和管理,看他的几个主要方法就知道了:

    getBean,可以根据name、type等获取bean对象
  1. containsBean,是否bean工厂中有某个对象
  2. isSingleton,判断是否是单例
  3. isTypeMatch,判断改name是否匹配类型
  4. getType,根据bean名字获取类型
  5. getAliases。获取别名数组
    看着主要几个接口实现,基本都是围绕bean所做的,然后根据接口再看他的实现类就方便许多了,

DefaultListableBeanFactory

    containsBeanDefinition,查看是否包含某个bean定义,因为该类维护了一个Map<String, BeanDefinition> beanDefinitionMap属性。
  1. determineAutowireCandidate,决定注入哪个bean,@Primary-->优先级最高--->name
  2. doResolveDependency,解析依赖,进行注入
  3. registerBeanDefinition,注册bean定义到beanDefinitionMap属性
  4. preInstantiateSingletons,进行创建bean实例

具体使用操作也是基本类似的

AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(.getBeanDefinition(;  
beanDefinition.setBeanClass(UserService.class;  
defaultListableBeanFactory.registerBeanDefinition("userService",beanDefinition;  
  
UserService userService1 = (UserService defaultListableBeanFactory.getBean("userService";  
userService1.test(;

从他的结构图也能看出来:

AbstractBeanFactory

    doGetBean,获取bean的主要逻辑,没有则创建
  1. getMergedBeanDefinition,bean定义的合并逻辑,主要是将父类beanfactory中的属性被子类覆盖

AbstractAutowireCapableBeanFactory

继承自刚才提到的AbstractBeanFactory,主要方法如下:

    autowireByName,按照name注入
  1. autowireByType,根据类型
  2. createBean,创建bean流程,实例化前可以使用BeanPostProcessors后置处理器
  3. createBeanInstance,正在创建bean,这边使用到了之前入门讲过的推断构造器实现实例化
  4. doCreateBean,创建bean,循环依赖、属性填充、初始化
  5. initializeBean,初始化bean,包括初始化前、初始化、初始化后
  6. instantiateUsingFactoryMethod,利用factorymethod初始化bean
  7. invokeAwareMethods,初始化bean时的回调函数Aware接口
  8. populateBean,初始化之前,属性赋值

HierarchicalBeanFactory

这里说下HierarchicalBeanFactory类,他只是一个接口类,但是如果想要使用beanfactory的层次结构,例如获取父beanfactory,那就必须实现HierarchicalBeanFactory类,比如前面说的bean定义的合并逻辑,就需要获取父beanfactory,从而实现父子bean定义的覆盖合并

ApplicationContext

更加强大,它本身并没有太多方法,但是它继承了很多接口,因为接口之间是可以多继承的。

AnnotationConfigApplicationContext

一看这个类,大家都知道了,我们用的实例全是用这个类去启动我们的spring的,我们看看他的主要方法:

    AnnotationConfigApplicationContext,构造器,会初始化DefaultListableBeanFactory、AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScanner;然后开始调用refresh(方法。
  1. register,会使用编程式定义将bean注入spring容器。就如我们的APPConfig
  2. scan,走ClassPathBeanDefinitionScanner的scan,扫描包路径,将声明式的bean注入进spring容器
  3. setBeanNameGenerator,bean名称生成器

ClassPathXmlApplicationContext

BeanPostProcessor

BeanPostProcess表示Bena的后置处理器,可以有多个BeanPostProcessor,我们自己也可以去定义一个BeanPostProcessor;

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName {
        if ("userService".equals(beanName {
            System.out.println("userService";
            return new User(;
        }
        System.out.println("MyBeanPostProcessor.postProcessBeforeInitialization";
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName {
        System.out.println("MyBeanPostProcessor.postProcessAfterInitialization";
        return bean;
    }

我们可以通过实现bean的后置处理器,来对某一个bean或者所有bean的进行干预,博主只是随便写了一个,没有什么太大意义。

BeanFactoryPostProcessor

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory throws BeansException {
        System.out.println("加工beanFactory";
    }
}

FactoryBean

FactoryBean和BeanFactory不是一个东西,大家不要混淆两个概念,BeanFactory是管理我们注入的bean等,而FactoryBean本身也会被Spring管理,一旦Spring知道我们的bean实现了FactoryBean,那么会自动调用getObject方法获取我们自己创建的bean,这个bean完完全全交给我们自己创建了,我们可以这样定义一个FactoryBean:


@Component
public class MyFactoryBean implements FactoryBean {

    @Override
    public Object getObject( throws Exception {
        UserService service = new UserService(;
        return service;
    }

    @Override
    public Class<?> getObjectType( {
        return UserService.class;
    }

}

但是需要注意的是,这些注入UserService时,是不会有属性依赖注入的,毕竟他没有走bean的生命创建周期。细心的朋友会发现,这根我在配置类中写@bean形式的类有啥区别,现象来讲,他俩都可以被创建出来,但是值得一提的是,FactoryBean创建出来的bean是没走spring定义的bean生命周期的。

MetadataReader、ClassMetadata、AnnotationMetadata

        SimpleMetadataReaderFactory simpleMetadataReaderFactory = new SimpleMetadataReaderFactory(;
        MetadataReader metadataReader = simpleMetadataReaderFactory.getMetadataReader("com.xiaoyu.service.UserService";
        System.out.println(metadataReader.getClassMetadata(.getClassName(;
        metadataReader.getAnnotationMetadata(.getAnnotationTypes(.forEach(System.out::println;

结语

通过本文的解析,我们大致了解了Spring框架中的一些关键组件及其用途,这有助于我们在深入理解Spring源码过程中建立起一个整体框架。Spring源码量很大,要真正理解透彻还需要投入大量时间进行细致学习和总结。但如果先对一些关键组件有一个大致的认识,有助于我们进行针对性学习,避免迷失在繁杂的细节中。希望本文能够对读者有一定的帮助,更希望读者在学习Spring源码的过程中,不断总结和提高,并在一定阶段有所突破。祝读者顺利!

编程笔记 » Spring源码系列:核心概念解析

赞同 (35) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽