广告位联系
返回顶部
分享到

Spring中Bean注入源码介绍

java 来源:互联网 作者:佚名 发布时间:2023-01-16 21:39:53 人浏览
摘要

BeanDefinition和Bean 在Spring中Bean的注入涉及两部分: BeanDefinition Bean 两个对象存在先后顺序,先注入BeanDefinition之后才执行Bean对象的注入。 那么两者有什么关联呢? BeanDefinition和Bean的关系

BeanDefinition和Bean

在Spring中Bean的注入涉及两部分:

  • BeanDefinition
  • Bean

两个对象存在先后顺序,先注入BeanDefinition之后才执行Bean对象的注入。

那么两者有什么关联呢?

BeanDefinition和Bean的关系:可以理解为BeanDefinition是Bean的包装类,类似Java中类和属性的关系。

BeanDefinition是对Bean对象的包装,BeanDefinition中封装了Bean相关的描述,比如bean对象,bean的单例还是原型、bean的父级、懒加载方式等等。

1

2

3

4

5

6

7

8

9

10

11

12

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

    void setScope(@Nullable String scope);

    @Nullable

    String getScope();

    void setLazyInit(boolean lazyInit);

    boolean isLazyInit();

}

//bean的原数据

public interface BeanMetadataElement {

    @Nullable

    Object getSource();

}

在BeanDefinition中继承了BeanMetadataElement,该类是Bean的原数据,该类中实例化了Bean对象为Object。因此在BeanDefinition中调用getSource就可以获取到Bean对象。

分清楚BeanDefinition和Bean之后再看BeanDefinition的注入,因为只有注入了BeanDefinition才会注入后续的Bean。

BeanDefinition的注入

BeanDefinitionRegistry接口

BeanDefinitin的注入通过接口BeanDefinitionRegistry抽象了各种对BeanDefinition的操作,例如

  • BeanDefinitionRegistry#registerBeanDefinition(注入到beanDefinition中)
  • BeanDefinitionRegistry#removeBeanDefinition(从beanDefinition容器中移除)
  • BeanDefinitionRegistry#getBeanDefinition(获取BeanDefinition)

1

2

3

4

5

6

7

8

9

10

public interface BeanDefinitionRegistry extends AliasRegistry {

    void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)

            throws BeanDefinitionStoreException;

    void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

    BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

    boolean containsBeanDefinition(String beanName);

    String[] getBeanDefinitionNames();

    int getBeanDefinitionCount();

    boolean isBeanNameInUse(String beanName);

}

该接口是操作BeanDefinition的基础接口,该类是一个接口类型并不是一个抽象类,因此该接口中不会定义任何BeanDefinition的容器,BeanDefinition的容器只在各实现类中定义并使用。任何需要操作BeanDefinition的实现都需要实现该接口。

BeanDefinitionRegistry的实现类

找到操作BeanDefinition的接口就可以通过接口查看接口的实现类,进而找到BeanDefinition的应用。

BeanDefinition常见的几个实现类有:

  • DefaultListableBeanFactory
  • SimpleBeanDefinitionRegistry

SimpleBeanDefinitionRegistry

1

2

3

4

5

6

7

8

9

10

11

12

public class SimpleBeanDefinitionRegistry extends SimpleAliasRegistry implements BeanDefinitionRegistry {

    /**beanDefinition的容器,通过ConcurrentHashMap实现. */

    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(64);

    //该类的实现方法只是实现了最简单的beanDefinition的注入,在Java开发环境中并不会使用该实现类

    @Override

    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)

            throws BeanDefinitionStoreException {

        Assert.hasText(beanName, "'beanName' must not be empty");

        Assert.notNull(beanDefinition, "BeanDefinition must not be null");

        this.beanDefinitionMap.put(beanName, beanDefinition);

    }

}

该实现类中只做了最简单的注入功能,没有任何的逻辑处理,因此在实际开发过程中Spring并不会使用该类。

DefaultListableBeanFactory

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {

        //beanDefinition的容器

        private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

        //向BeanFactory中注入BeanDefinition

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

            Assert.hasText(beanName, "Bean name must not be empty");

            Assert.notNull(beanDefinition, "BeanDefinition must not be null");

            if (beanDefinition instanceof AbstractBeanDefinition) {

                try {

                    ((AbstractBeanDefinition) beanDefinition).validate();

                }

                catch (BeanDefinitionValidationException ex) {

                    throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,

                            "Validation of bean definition failed", ex);

                }

            }

            BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);

            //判断beanDefinition容器中是否已存在该beanDefinition

            if (existingDefinition != null) {

                //是否可以覆盖

                if (!isAllowBeanDefinitionOverriding()) {

                    throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);

                } else if (existingDefinition.getRole() < beanDefinition.getRole()) {

                    // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE

                    if (logger.isInfoEnabled()) {

                        logger.info("Overriding user-defined bean definition for bean '" + beanName +

                                "' with a framework-generated bean definition: replacing [" +

                                existingDefinition + "] with [" + beanDefinition + "]");

                    }

                } else if (!beanDefinition.equals(existingDefinition)) {

                    if (logger.isDebugEnabled()) {

                        logger.debug("Overriding bean definition for bean '" + beanName +

                                "' with a different definition: replacing [" + existingDefinition +

                                "] with [" + beanDefinition + "]");

                    }

                } else {

                    if (logger.isTraceEnabled()) {

                        logger.trace("Overriding bean definition for bean '" + beanName +

                                "' with an equivalent definition: replacing [" + existingDefinition +

                                "] with [" + beanDefinition + "]");

                    }

                }

                //覆盖beanDefinition

                this.beanDefinitionMap.put(beanName, beanDefinition);

            } else { //容器中不存在该beanDefinition的处理

                if (hasBeanCreationStarted()) {

                    synchronized (this.beanDefinitionMap) { //对beanDefinition加锁

                        //注入该beanDefinition

                        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);

        }

    }

}

DefaultListableBeanFactory是默认使用的注入BeanDefinition的实现类,可以看到该实现类中对注入BeanDefinition做了很多的逻辑判断,日常开发启动容器过程中都会使用该实现类注入BeanDefinition进行后续的Bean注入。

Bean的注入

BeanDefinition注入后后续执行Bean的注入,bean注入的方式也是将bean注入到bean的容器中,因此在Spring中BeanDefinition和Bean都是通过容器化的方式操作的,那么在Bean的注入中也通过对应的接口定义对Bean的操作,该接口就是SingletonBeanRegistry。

SingletonBeanRegistry接口

该接口实现了对Bean的操作:

  • SingletonBeanRegistry#registerSingleton(将bean注入到容器中)
  • SingletonBeanRegistry#getSingleton(从容器中获取bean)

1

2

3

4

5

6

7

8

9

10

11

12

public interface SingletonBeanRegistry {

    //注入bean

    void registerSingleton(String beanName, Object singletonObject);

    //获取bean

    @Nullable

    Object getSingleton(String beanName);

    //是否存在bean

    boolean containsSingleton(String beanName);

    String[] getSingletonNames();

    int getSingletonCount();

    Object getSingletonMutex();

}

SingletonBeanRegistry的实现类

SingletonBeanRegistry的实现类有多个,分别为:

  • AbstractBeanFactory
  • DefaultListableBeanFactory
  • DefaultSingletonBeanRegistry
  • FactoryBeanRegistrySupport
  • AbstractAutowireCapableBeanFactory

下面说两个有代表性的:AbstractBeanFactory和DefaultSingletonBeanRegistry

AbstractBeanFactory

该实现类是一个抽象类,即该类是bean的工厂类,其中主要实现的是可以复用的具体逻辑,该抽象类中包含获取bean、beanPostProcessor、初始化bean、销毁bean等对bean的操作抽象类。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {

    //获取bean的方式平时使用ApplicationContext就是最终调用该方法

    public Object getBean(String name) throws BeansException {

        return doGetBean(name, null, null, false);

    }

    @Override

    public <T> T getBean(String name, Class<T> requiredType) throws BeansException {

        return doGetBean(name, requiredType, null, false);

    }

    @Override

    public Object getBean(String name, Object... args) throws BeansException {

        return doGetBean(name, null, args, false);

    }

    public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args)

            throws BeansException {

        return doGetBean(name, requiredType, args, false);

    }

    /**

    * 从容器中获取bean的主要逻辑

    */

    protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,

            @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

        final String beanName = transformedBeanName(name);

        Object bean;

        // Eagerly check singleton cache for manually registered singletons.

        Object sharedInstance = getSingleton(beanName);

        if (sharedInstance != null && args == null) {

            if (logger.isTraceEnabled()) {

                if (isSingletonCurrentlyInCreation(beanName)) {

                    logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +

                            "' that is not fully initialized yet - a consequence of a circular reference");

                }

                else {

                    logger.trace("Returning cached instance of singleton bean '" + beanName + "'");

                }

            }

            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);

        }

        else {

            //省略部分代码

            try {

                //先获取beanDefinition

                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

                checkMergedBeanDefinition(mbd, beanName, args);

                // Guarantee initialization of beans that the current bean depends on.

                String[] dependsOn = mbd.getDependsOn();

                if (dependsOn != null) {

                    for (String dep : dependsOn) {

                        if (isDependent(beanName, dep)) {

                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,

                                    "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");

                        }

                        registerDependentBean(dep, beanName);

                        try {

                            getBean(dep);

                        }

                        catch (NoSuchBeanDefinitionException ex) {

                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,

                                    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);

                        }

                    }

                }

                // 单例模式下获取bean的方式

                if (mbd.isSingleton()) {

                    sharedInstance = getSingleton(beanName, () -> {

                        try {

                            return createBean(beanName, mbd, args);

                        }

                        catch (BeansException ex) {

                            // Explicitly remove instance from singleton cache: It might have been put there

                            // eagerly by the creation process, to allow for circular reference resolution.

                            // Also remove any beans that received a temporary reference to the bean.

                            destroySingleton(beanName);

                            throw ex;

                        }

                    });

                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);

                }

                else if (mbd.isPrototype()) {//原型模式下的bean的获取

                    // It's a prototype -> create a new instance.

                    Object prototypeInstance = null;

                    try {

                        beforePrototypeCreation(beanName);

                        //原型模式每次都需要创建bean

                        prototypeInstance = createBean(beanName, mbd, args);

                    }

                    finally {

                        afterPrototypeCreation(beanName);

                    }

                    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);

                }

                else {

                    String scopeName = mbd.getScope();

                    final Scope scope = this.scopes.get(scopeName);

                    if (scope == null) {

                        throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");

                    }

                    try {

                        Object scopedInstance = scope.get(beanName, () -> {

                            beforePrototypeCreation(beanName);

                            try {

                                return createBean(beanName, mbd, args);

                            }

                            finally {

                                afterPrototypeCreation(beanName);

                            }

                        });

                        bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);

                    }

                    catch (IllegalStateException ex) {

                        throw new BeanCreationException(beanName,

                                "Scope '" + scopeName + "' is not active for the current thread; consider " +

                                "defining a scoped proxy for this bean if you intend to refer to it from a singleton",

                                ex);

                    }

                }

            }

            catch (BeansException ex) {

                cleanupAfterBeanCreationFailure(beanName);

                throw ex;

            }

        }

        //省略部分代码

        return (T) bean;

    }

    //将实现beanPostProcessor的实现类加入到链表中用于对bean的前置或者后置处理

    @Override

    public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {

        Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");

        // Remove from old position, if any

        this.beanPostProcessors.remove(beanPostProcessor);

        // Track whether it is instantiation/destruction aware

        if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {

            this.hasInstantiationAwareBeanPostProcessors = true;

        }

        if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {

            this.hasDestructionAwareBeanPostProcessors = true;

        }

        // Add to end of list

        this.beanPostProcessors.add(beanPostProcessor);

    }

    //销毁bean的方法

    @Override

    public void destroyBean(String beanName, Object beanInstance) {

        destroyBean(beanName, beanInstance, getMergedLocalBeanDefinition(beanName));

    }

    protected void destroyBean(String beanName, Object bean, RootBeanDefinition mbd) {

        new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), getAccessControlContext()).destroy();

    }

}

DefaultSingletonBeanRegistry

该实现类通过名字也可以推断出该实现类是对单例bean的注入,该类中实现了bean的所有容器,平时开发过程中Spring容器启动就是使用了该实现类中的容器,该实现类是对bean最终注入的实现,涉及的四个容器主要有:

  • singletonObjects
  • singletonFactories
  • earlySingletonObjects
  • registeredSingletons

四个容器其中三个的核心作用是解决循环依赖,这里不展开说。

找一条主线梳理下Bean注入的过程,当BeanDefinition注入成功后,后续执行bean的注入,以AbstractAutowireCapableBeanFactory的实现为例,该实现类中会对bean的注入,整个注入的链路如下:

  • 获取资源数据:CommonAnnotationBeanPostProcessor#autowireResource
  • 通过beanName解析bean:AbstractAutowireCapableBeanFactory#resolveBeanByName
  • 调用抽象类中获取bean:AbstractBeanFactory#getBean
  • 执行抽象类中获取bean的核心逻辑:AbstractBeanFactory#doGetBean
  • bean不存在时创建bean:AbstractAutowireCapableBeanFactory#createBean
  • 获取单例bean:efaultSingletonBeanRegistry#getSingleton
  • 单例bean不存在将类注入到容器中:DefaultSingletonBeanRegistry#addSingleton

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {

    //单例bean的容器,开发过程中获取的bean都是从该容器中获取的:即所谓的一级缓存

    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

    //单例bean的beanFactory的容器:即所谓的三级缓存

    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

    //提前初始化的bean的容器,该容器的bean并没有任何属性值只是提前将bean注入到该容器中用于后续的判断

    //即所谓的二级缓存

    private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

    //已注册的单例bean的beanName列表

    private final Set<String> registeredSingletons = new LinkedHashSet<>(256);

    //注入bean的方法

    public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {

        Assert.notNull(beanName, "Bean name must not be null");

        Assert.notNull(singletonObject, "Singleton object must not be null");

        synchronized (this.singletonObjects) {

            Object oldObject = this.singletonObjects.get(beanName);

            if (oldObject != null) {

                throw new IllegalStateException("Could not register object [" + singletonObject +

                                                "] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");

            }

            addSingleton(beanName, singletonObject);

        }

    }

    /**

    * 将bean注入容器中,操作四个容器主要用于bean的循环依赖问题

    */

    protected void addSingleton(String beanName, Object singletonObject) {

        synchronized (this.singletonObjects) {

            this.singletonObjects.put(beanName, singletonObject);

            this.singletonFactories.remove(beanName);

            this.earlySingletonObjects.remove(beanName);

            this.registeredSingletons.add(beanName);

        }

    }

}

总结

以上就是对bean注入从源码的梳理,该梳理主要从bean注入前的准备(beanDefinition的注入)和bean注入的实现来完成,从整个梳理中学到最多的主要有两点:

  • 抽象的思想:在BeanDefinition的实现和Bean的实现逻辑中,都完成高度抽象并且遵循单一原则和高度抽象,代码的可扩展性和复用性很高,我们作为开发者也可以通过Spring暴露的各种Registry接口实现对Bean的操作。
  • 容器化思想:从BeanDefinition和Bean的注入来看,整个的实现思路都是基于容器化思想来实现的,将开发中需要关心的对象都实例化到容器中,开发者在使用时只要从容器中获取即可,并且获取bean的方式也很灵活,开发者在使用和扩展性上更便利。

对于源码的学习自己理解来说并不是背其中的代码,而是学习大佬实现代码的思想,为什么可以抽象出扩展性这么高的代码,并且从源头梳理下来都能很轻松的按照主线一步一步梳理到目的地,这也是每个开发者需要学习的地方,提高自己代码的可读性和可扩展性,能够掌握面向对象的核心:封装、继承、多态。


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 : https://juejin.cn/post/7185934630116130872
相关文章
  • Java经典面试题最全汇总208道(六)

    Java经典面试题最全汇总208道(六)
    短时间提升自己最快的手段就是背面试题,最近总结了Java常用的面试题,分享给大家,希望大家都能圆梦大厂,加油,我命由我不由天。
  • Spring中Bean注入源码介绍

    Spring中Bean注入源码介绍
    BeanDefinition和Bean 在Spring中Bean的注入涉及两部分: BeanDefinition Bean 两个对象存在先后顺序,先注入BeanDefinition之后才执行Bean对象的注入。 那
  • Java流程控制语句最全汇总(上篇)

    Java流程控制语句最全汇总(上篇)
    本章是关于Java流程控制语句的最全汇总,本篇为汇总上篇。 流程是人们生活中不可或缺的一部分,它表示人们每天都在按照一定的流程做事
  • Java流程控制语句最全汇总(中篇)

    Java流程控制语句最全汇总(中篇)
    本章是关于Java流程控制语句的最全汇总,本篇为汇总中篇。 流程是人们生活中不可或缺的一部分,它表示人们每天都在按照一定的流程做事
  • Mapper与Mapper.xml文件之间匹配的问题介绍

    Mapper与Mapper.xml文件之间匹配的问题介绍
    Mapper与Mapper.xml文件之间匹配问题 这里我们做一个实例 user实体类 1 2 3 4 5 6 public class User { private Integer id; private String username; private String pas
  • Gauva使用ListenableFuture介绍说明
    一、ListenableFuture 介绍 并发是一个困难问题,但是通过强大和强大的抽象能够显著的简化工作。为了简化问题,Gauva使用ListenableFuture扩展了
  • MyBatis一级与二级缓存相关配置

    MyBatis一级与二级缓存相关配置
    1.MyBatis的一级缓存 一级缓存是 SqlSession 级别的,通过同一个 SqlSession 查询的数据会被缓存,下次查询相同的数据,就 会从缓存中直接获取,
  • Java阻塞队列BlockingQueue基础与使用
    什么是阻塞队列 阻塞队列本质上还是一种队列,遵循先进先出,后进后出的原则,在此基础上,如果出队时阻塞队列为空,则会使当前线程
  • Java实现将每日新闻添加到自己博客中
    最近新整了个博客网站,同事在gitee上找的,还不错,gitee上的地址在这里:拾壹博客管理系统。 别人的业务,再好也有不满足自己的地方,
  • Java实现每日给女友微信发送早安信息
    据说这个功能最近在抖音上很火,我没有抖音,没有看到。 但是我在网上看了,相关案例确实很多,但是大家都是借助于了微信服务号,在
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计