java
主页 > 软件编程 > java >

Spring中Bean注入源码介绍

2023-01-16 | 佚名 | 点击:

BeanDefinition和Bean

在Spring中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的操作,例如

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常见的几个实现类有:

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的操作:

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和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最终注入的实现,涉及的四个容器主要有:

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

找一条主线梳理下Bean注入的过程,当BeanDefinition注入成功后,后续执行bean的注入,以AbstractAutowireCapableBeanFactory的实现为例,该实现类中会对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

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注入的实现来完成,从整个梳理中学到最多的主要有两点:

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

原文链接:https://juejin.cn/post/7185934630116130872
相关文章
最新更新