spring

spring核心类分析

​ 要想读懂spring源码就需要知道spring核心类的脉络,及核心类的作用。先有核心类的脉络体系知识后,带着脉络看源码调用流程事半功倍


ApplicationContext

Application类图


ApplicationContext接口代表了Spring Ioc容器,它负责实例化、配置、组装bean。容器通过读取配置元数据获取对象的实例化、配置和组装的描述信息


​ Spring提供几个开箱即用的ApplicationContext接口的实现类

  • ClassPathXmlApplicationContext

    • 从classpath的XML配置文件中读取上下文

    • ApplicationContext context = new ClassPathXmlApplicationContext(“bean.xml”);

  • FileSystemXmlApplicationContext

    • 由文件系统中的XML配置文件读取上下文
    • ApplicationContext context = new FileSystemXmlApplicationContext(“bean.xml”);
  • XmlWebApplicationContext

    • 由Web应用的XML文件读取上下文
  • AnnotationConfigApplicationContext

    • spring boot使用的基于注解的上下文

BeanFactory 和 ApplicationContext

尽量使用ApplicationContext除非你有更好的理由不用它

因为ApplicationContext包括了BeanFactory的所有功能,通常也优于BeanFactory,除非一些少数的场景,例如:在受资源约束的嵌入式设备上运行一个嵌入式应用,它的内存消耗可能至关重要,并且可能会产生字节。然而,对于大多数典型的企业级应用和系统来说,ApplicationContext才是你想使用的。Spring大量使用了BeanPostProcessor扩展点(以便使用代理等)。如果你仅仅只使用简单的BeanFactory,很多的支持功能将不会有效,例如:事务和AOP,但至少不会有额外的步骤。这可能会比较迷惑,毕竟配置又没有错。

FeatureBeanFactoryApplicationContext
Bean实例化/装配
BeanPostProcessor自动注册
BeanFactoryPostProcessor自动注册
MessageSource便捷访问(针对i18n)
ApplicationEvent 发布

区别

BeanFactory提供了ioc容器的基本功能,主要负责bean的实例化和装配,ApplicationContext代表了spring ioc容器,ApplicationContext继承于BeanFactory包含BeanFactory的所有功能,并且还提供了BeanPostProcessor,ApplicationEvent等功能,比BeanFaction功能更加强大


AnnotationConfigApplicationContext

AnnotationConfigApplicationContext,在 Spring 3.0 中 是 新加入的,从此spring进入注解配置时代,支持注解配置

  • @Configuration

  • @Bean

  • @Component

  • @Autowired

从类图结构中看出,AbstractApplicationContext是所有开箱即用的ApplicationContext接口的实现类的中枢,图中出现另一个重要spring顶级接口体系AliasRegistry (别名注册表)及它的子接口BeanDefinitionRegistry (Bean 定义注册表)


注册表体系

注册表体系主要提供了bean别名注册,单例bean注册,bean循环依赖三级缓存

AliasRegistry

bean别名注册表,作为bean定义的最顶层接口,这个接口定义了管理别名的一些方法,主要作用是将名字-别名映射存到内存中。提供查找和校验的接口

  • registerAlias 注册一个bean的别名
  • removeAlias 删除注册的别名
  • isAlias 确定一个名字是否是别名
  • getAliases 返回一个名字注册的别名列表。当传入bean的名称带有&前缀时,转换为别名后也会返回带&前缀的别名,这种特殊处理参考BeanFactory#FACTORY_BEAN_PREFIX

BeanDefinition

在了解BeanDefinitionRegistry (Bean 定义注册表)之前必须知道BeanDefinition是什么

在 Spring 容器中,我们广泛使用的是一个一个的 Bean,BeanDefinition(接口) 从名字上就可以看出是关于 Bean 的定义

事实上就是这样,我们在 XML 文件中,java配置类中配置的 Bean 的各种属性,这些属性不仅仅是和对象相关,Spring 容器还要解决 Bean 的生命周期、销毁、初始化等等各种操作,我们定义的关于 Bean 的生命周期、销毁、初始化等操作总得有一个对象来承载,那么这个对象就是 BeanDefinition的实现类。文章后续会讲到spring如何将bean的配置转成BeanDefinition,又是如何使用BeanDefinitionRegistryPostProcessor后置处理器使用BeanDefinition对bean进行注册流程


  1. 首先一开始定义了两个变量用来描述 Bean 是不是单例的,后面的 setScope/getScope 方法可以用来修改/获取 scope 属性。
  2. ROLE_xxx 用来描述一个 Bean 的角色,ROLE_APPLICATION 表示这个 Bean 是用户自己定义的 Bean;ROLE_SUPPORT 表示这个 Bean 是某些复杂配置的支撑部分;ROLE_INFRASTRUCTURE 表示这是一个 Spring 内部的 Bean,通过 setRole/getRole 可以修改。
  3. setParentName/getParentName 用来配置 parent 的名称,这块可能有的小伙伴使用较少,这个对应着 XML 中的 <bean parent=""> 配置。
  4. setBeanClassName/getBeanClassName 这个就是配置 Bean 的 Class 全路径,对应 XML 中的 <bean class=""> 配置。
  5. setLazyInit/isLazyInit 配置/获取 Bean 是否懒加载,这个对应了 XML 中的 <bean lazy-init=""> 配置。
  6. setDependsOn/getDependsOn 配置/获取 Bean 的依赖对象,这个对应了 XML 中的 <bean depends-on=""> 配置。
  7. setAutowireCandidate/isAutowireCandidate 配置/获取 Bean 是否是自动装配,对应了 XML 中的 <bean autowire-candidate=""> 配置。
  8. setPrimary/isPrimary 配置/获取当前 Bean 是否为首选的 Bean,对应了 XML 中的 <bean primary=""> 配置。
  9. setFactoryBeanName/getFactoryBeanName 配置/获取 FactoryBean 的名字,对应了 XML 中的 <bean factory-bean=""> 配置,factory-bean 松哥在之前的入门视频中讲过,小伙伴们可以参考这里:https://www.bilibili.com/video/BV1Wv41167TU。
  10. setFactoryMethodName/getFactoryMethodName 和上一条成对出现的,对应了 XML 中的 <bean factory-method=""> 配置,不再赘述。
  11. getConstructorArgumentValues 返回该 Bean 构造方法的参数值。
  12. hasConstructorArgumentValues 判断上一条是否是空对象。
  13. getPropertyValues 这个是获取普通属性的集合。
  14. hasPropertyValues 判断上一条是否为空对象。
  15. setInitMethodName/setDestroyMethodName 配置 Bean 的初始化方法、销毁方法。
  16. setDescription/getDescription 配置/返回 Bean 的描述。
  17. isSingleton Bean 是否为单例。
  18. isPrototype Bean 是否为原型。
  19. isAbstract Bean 是否抽象。
  20. getResourceDescription 返回定义 Bean 的资源描述。
  21. getOriginatingBeanDefinition 如果当前 BeanDefinition 是一个代理对象,那么该方法可以用来返回原始的 BeanDefinition

BeanDefinition实现类


BeanDefinitionRegistry

BeanDefinitionRegistry类图


​ 我们定义bean时不管是通过java config方式,还是xml配置文件的方式,最终都会解析成BeanDefinition,而这些BeanDefinition都需要注册到容器中,这个注册的过程是通过接口org.springframework.beans.factory.support.BeanDefinitionRegistry来定义的,也就是说BeanDefinitionRegistry子类具备注册bean的定义到ioc容器的能力


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
>org.springframework.beans.factory.support.BeanDefinitionRegistry

>// 定义bean定义的注册相关方法的接口
public interface BeanDefinitionRegistry extends AliasRegistry {

// 在注册中心注册一个bean定义,必须支持RootBeanDefinition和ChildBeanDefinition
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException;

// 移除对应bean名称的bean定义
void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

// 返回给定bean名称对应的bean定义
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

// 检查注册中心是否包含指定名称的bean定义
boolean containsBeanDefinition(String beanName);

// 返回注册中心中所有的bean定义的名称的数组
String[] getBeanDefinitionNames();

// 返回注册中心中bean定义的个数
int getBeanDefinitionCount();

// 返回beanName是否被占用,即已经在注册中心中注册了bean定义
boolean isBeanNameInUse(String beanName);
}

bean注册的流程

sequenceDiagram
后置处理器 ->> 扫描配置 : xml、java config
扫描配置 ->> BeanDefinition : 解析生成bean定义对象
BeanDefinition ->> DefaultListableBeanFactory : BeanDefinition注册
DefaultListableBeanFactory ->> DefaultSingletonBeanRegistry : 单例bean实例化注册到ioc容器

SingletonBeanRegistry

单例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
public interface SingletonBeanRegistry {

// 以指定的名字 把Object放进去
// 1、给定的Object必须是被完全初始化了的(比如new出来的)
// 2、此注册接口不会提供任何用以初始化的回调函数(比如:InitializingBean、afterPropertiesSet都是不会执行的)
// 3、如果此接口的实现类是一个BeanFactory,最好最好最好将你的类注册成Bean Definition而不是直接使用对象(这样就可以使你定义的Bean收到initialization和destruction回调)
void registerSingleton(String beanName, Object singletonObject);

// 仅仅返回已经初始化完成的Bean,对于还没有初始化的Bean Definition不予以考虑
// 但是要注意,此方法**并不支持使用别名**对Bean进行查找,如果只有别名的话,要先通过BeanFactory的接口获取到Bean对应的全限定名称(transformedBeanName())
Object getSingleton(String beanName);

// 检查此实例是否包含指定名字的并且!!!已经初始化完成的单例Bean(不支持别名查找)
// BeanFactory#containsBean是containsSingleton(beanName) || containsBeanDefinition(beanName)
boolean containsSingleton(String beanName);

// 返回所有单例 Bean 的名称
String[] getSingletonNames();

// 返回已注册的单例 Bean 实例数量
int getSingletonCount();

// 返回当前使用的单例锁,主要提供给外部协作者使用
Object getSingletonMutex();
}

*DefaultSingletonBeanRegistry

DefaultSingletonBeanRegistry是整个ioc容器比较核心的类,因为它负责存储、提供单例的bean实例、维护bean之间关系以及维护已经注册的bean的名称

  • 解决循环依赖的三级缓存,存储单例bean
  • 注册单例bean
  • 添加单例bean到ioc容器
  • 获取单例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
// 单例对象的缓存:从beanname到bean实例  一级缓存,存放完整的 Bean
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 单例工厂的缓存:从beanname到ObjectFactory 三级缓存,存放的是 Bean 工厂,主要是生产 Bean,解决循环
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
// 早期单例对象的缓存:从beanname到bean实例 二级缓存 解决循环依赖二级缓存,存放提前暴露的Bean,Bean 是不完整的,未完成属性注入和执行 init 方法
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
// 一组已注册的单例,包含按注册顺序排列的beanname
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
// 正在创建的单例的beanName的集合
private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
// 当前不检查的bean的集合
private final Set<String> inCreationCheckExclusions = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
// 异常集合
private Set<Exception> suppressedExceptions;
// 当前是否在销毁bean中
private boolean singletonsCurrentlyInDestruction = false;
// 具有销毁能力的bean实例,DisposableBean的实现类
private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
// 内部bean和外部bean之间关系
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);
// 指定bean与依赖指定bean的集合,比如bcd依赖a,那么就是key为a,bcd为value
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
// 指定bean与指定bean依赖的集合,比如a依赖bcd,那么就是key为a,bcd为value
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);

重要方法说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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);
}
}
  • addSingleton

    单例bean加入到缓存

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    protected void addSingleton(String beanName, Object singletonObject) {
    synchronized (this.singletonObjects) {
    // 加入单例对象的缓存(一级缓存)
    this.singletonObjects.put(beanName, singletonObject);
    // 既然加入了单例对象的缓存,那singletonFactories和earlySingletonObjects就不再持有
    // 删除三级级缓存
    this.singletonFactories.remove(beanName);
    // 删除二级缓存
    this.earlySingletonObjects.remove(beanName);
    // 加入已注册的bean
    this.registeredSingletons.add(beanName);
    }
    }
  • addSingletonFactory

    添加三级缓存

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    //增加单例工程的单例,取单例的时候调用getObject方法
    protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(singletonFactory, "Singleton factory must not be null");
    synchronized (this.singletonObjects) {
    if (!this.singletonObjects.containsKey(beanName)) {
    this.singletonFactories.put(beanName, singletonFactory);
    this.earlySingletonObjects.remove(beanName);
    this.registeredSingletons.add(beanName);
    }
    }
    }

    @FunctionalInterface
    public interface ObjectFactory<T> {
    T getObject() throws BeansException;
    }
  • getSingleton

    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
    public Object getSingleton(String beanName) {
    // 允许早期依赖
    return getSingleton(beanName, true);
    }
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    //如果一级缓存有直接返回
    Object singletonObject = this.singletonObjects.get(beanName);
    //缓存没有的情况但正在创建
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
    synchronized (this.singletonObjects) {
    //如果早期缓存中有,说明正在加载,则不处理直接返回
    //一级缓存拿不到尝试去二级缓存拿
    singletonObject = this.earlySingletonObjects.get(beanName);
    //allowEarlyReference允许是否从singletonFactories读取
    if (singletonObject == null && allowEarlyReference) {
    // 某些方法提前初始化的时候会调用addSingletonFactory,把ObjectFactory缓存在singletonFactories中
    // 二级缓存拿不到到三级缓存拿
    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
    if (singletonFactory != null) {
    //如果singletonFactories有,调用getObject方法返回
    singletonObject = singletonFactory.getObject();
    // singletonFactories产生的对象放入earlySingletonObjects中
    this.earlySingletonObjects.put(beanName, singletonObject);
    // 已经产生过一次对象了,所以就不能再用了,后面直接用earlySingletonObjects获取
    this.singletonFactories.remove(beanName);
    }
    }
    }
    }
    return singletonObject;
    }

    public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(beanName, "Bean name must not be null");
    synchronized (this.singletonObjects) {
    // 已经创建过了,直接返回
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null) {
    // 当前在销毁bean,不能创建
    if (this.singletonsCurrentlyInDestruction) {
    throw new BeanCreationNotAllowedException(beanName,
    "Singleton bean creation not allowed while singletons of this factory are in destruction " +
    "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
    }
    if (logger.isDebugEnabled()) {
    logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
    }
    // 创建前检查,记录正在加载状态
    beforeSingletonCreation(beanName);
    boolean newSingleton = false;
    // 如果当前没有异常,初始化异常集合
    boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
    if (recordSuppressedExceptions) {
    this.suppressedExceptions = new LinkedHashSet<>();
    }
    try {
    // 通过ObjectFactory的getObject创建bean,实际是回调createBean方法
    singletonObject = singletonFactory.getObject();
    newSingleton = true;
    }
    catch (IllegalStateException ex) {
    // Has the singleton object implicitly appeared in the meantime ->
    // if yes, proceed with it since the exception indicates that state.
    // 有可能是其他方式创建的bean
    singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null) {
    throw ex;
    }
    }
    catch (BeanCreationException ex) {
    if (recordSuppressedExceptions) {
    for (Exception suppressedException : this.suppressedExceptions) {
    ex.addRelatedCause(suppressedException);
    }
    }
    throw ex;
    }
    finally {
    if (recordSuppressedExceptions) {
    this.suppressedExceptions = null;
    }
    // 创建后检查,移除加载状态
    afterSingletonCreation(beanName);
    }
    if (newSingleton) {
    // 是新创建的bean,就加入到缓存中并移除其他缓存,如果是其他方式创建的bean,说明已经加入过缓存了,这边不再加入
    addSingleton(beanName, singletonObject);
    }
    }
    return singletonObject;
    }
    }
  • removeSingleton

    移除单例bean

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    protected void removeSingleton(String beanName) {
    synchronized (this.singletonObjects) {
    // 移除一级缓存
    this.singletonObjects.remove(beanName);
    // 移除三级缓存
    this.singletonFactories.remove(beanName);
    // 移除二级缓存
    this.earlySingletonObjects.remove(beanName);
    // 移除已注册的beanName名单
    this.registeredSingletons.remove(beanName);
    }
    }
  • beforeSingletonCreation

    创建单例bean之前的检查

    1
    2
    3
    4
    5
    6
    protected void beforeSingletonCreation(String beanName) {
    // 如果这个beanName要检查,看看add的时候返回什么,如果返回false,说明已经在创建了,抛异常
    if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
    throw new BeanCurrentlyInCreationException(beanName);
    }
    }
  • afterSingletonCreation

    创建单例bean之后的检查

    1
    2
    3
    4
    5
    6
    protected void afterSingletonCreation(String beanName) {
    // 如果这个beanName要检查,看看remove返回什么,如果返回false,说明已经创建完了。
    if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
    throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
    }
    }
  • registerDisposableBean

    注册具有销毁业务的bean,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public void registerDisposableBean(String beanName, DisposableBean bean) {
    synchronized (this.disposableBeans) {
    this.disposableBeans.put(beanName, bean);
    }
    }

    public interface DisposableBean {
    void destroy() throws Exception;
    }

BeanFactory体系

BeanFactory

  • BeanFactory为Spring的IoC功能提供了底层的基础,但是它仅仅被用于和第三方框架的集成,现在对于大部分的Spring用户来说都是历史了。BeanFactory及其相关的接口,例如:BeanFactoryAware,InitializingBean,DisposableBean,在Spring中仍然有所保留,目的就是为了让大量的第三方框架和Spring集成时保持向后兼容

  • BeanFactory和类加载器一样,也是有父BeanFactory的,具体体现在HierarchicalBeanFactory接口

BeanFactory和ApplicationContext


BeanFactory

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
package org.springframework.beans.factory;

public interface BeanFactory {

/**
* 用来引用一个实例,或把它和工厂产生的Bean区分开,就是说,如果一个FactoryBean的名字为a,那么,&a会得到那个Factory
*/
String FACTORY_BEAN_PREFIX = "&";

/*
* 四个不同形式的getBean方法,获取实例
*/
Object getBean(String name) throws BeansException;

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

<T> T getBean(Class<T> requiredType) throws BeansException;

Object getBean(String name, Object... args) throws BeansException;

boolean containsBean(String name); // 是否存在

boolean isSingleton(String name) throws NoSuchBeanDefinitionException;// 是否为单实例

boolean isPrototype(String name) throws NoSuchBeanDefinitionException;// 是否为原型(多实例)

boolean isTypeMatch(String name, Class<?> targetType)
throws NoSuchBeanDefinitionException;// 名称、类型是否匹配

Class<?> getType(String name) throws NoSuchBeanDefinitionException; // 获取类型

String[] getAliases(String name);// 根据实例的名字获取实例的别名

}

FACTORY_BEAN_PREFIX`

  • String FACTORY_BEAN_PREFIX = "&";
  • 根据beanName从spring容器获取实例,如果该实例不是FactoryBean类型,则直接返回该实例,这也是我们平时用的最多的、最普通的情况;如果该实例是FactoryBean类型,而name又是以&开头,也直接返回该实例,说明我们想要的就是FactoryBean实例;如果name不是以&开头,而该实例又是FactoryBean类型,则会调用该实例的getObject()来创建我们需要的目标实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 定义UserFactoryBean并使用别名注册
@Component("user")
public class UserFactoryBean implements FactoryBean<User> {
@Override
public User getObject() throws Exception {
// 假设User的实例化过程比较复杂,在此处进行User的实例化
return new User();
}
@Override
public Class<?> getObjectType() {
return User.class;
}
@Override
public boolean isSingleton() {
return true;
}
}

// 这种写法是获取 UserFactoryBean 实例
applicationContext.getBean(BeanFactory.FACTORY_BEAN_PREFIX + "user");

// 这种写法是获取 User实例
applicationContext.getBean("user");

*AutowireCapableBeanFactory

定义BeanFactory自动装配接口

  • 对于想拥有自动装配能力,并且想要把这种能力暴露给外部应用的beanfactory需要实现该接口
  • 正常情况下,不要实现该接口,应该实现BeanFactory或者ListableBeanFactory接口
  • 需要注意的是ApplicationContext并没实现该接口。如果需要用到自动装配功能的话,可以调用ApplicationContext.getAutowireCapableBeanFactory()方法,来获取此接口实例
  • 如果一个接口实现了该接口,很大程度上,还要实现BeanFactoryWare接口,这样子就能在上下文中返回BeanFactory

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
public interface AutowireCapableBeanFactory extends BeanFactory {

//变量指明工厂没有自动装配的bean
int AUTOWIRE_NO = 0;

//根据名称自动装配
int AUTOWIRE_BY_NAME = 1;

//根据类型自动装配
int AUTOWIRE_BY_TYPE = 2;

//标识按照贪婪策略匹配出的最符合的构造方法来自动装配的常量
int AUTOWIRE_CONSTRUCTOR = 3;


//根据bean的class内部自动装配,但是Spring3.0后被弃用
//先使用constructor进行装配,如果不成功就使用byType来装配
@Deprecated
int AUTOWIRE_AUTODETECT = 4;




//参数:bean的class类型
//返回:bean的实例
//功能:根据bean的class类型,创建对应的bean实例
<T> T createBean(Class<T> beanClass) throws BeansException;


//使用autowireBeanProperties装配属性
void autowireBean(Object existingBean) throws BeansException;

//自动装配属性
Object configureBean(Object existingBean, String beanName) throws BeansException;


//-------------------------------------------------------------------------
// Specialized methods for fine-grained control over the bean lifecycle
//-------------------------------------------------------------------------
//对bean的生命周期进行细粒度控制的专门方法

//执行完整的bean初始化(包括:initializedBean和BeanPostProcessors)
//autowireMode:根据名字或类型来决定自动装配的方式
Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;

//根据bean的类型和自动装配方式来自动装配
Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;

//根据自动装配方式来装配bean的属性
void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
throws BeansException;

//将参数中指定了那么的Bean,注入给定实例当中
void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;

//初始化参数中指定的Bean,调用任何其注册的回调函数如setBeanName、setBeanFactory等。
Object initializeBean(Object existingBean, String beanName) throws BeansException;

//调用参数中指定Bean的postProcessBeforeInitialization方法(如果实现了BeanPostProcessor接口)
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException;

//调用参数中指定Bean的postProcessorsAfterInitialization方法(如果实现了BeanPostProcessor接口)
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException;

//销毁参数中指定的Bean,同时调用此Bean上的DisposableBean和DestructionAwareBeanPostProcessors方法
void destroyBean(Object existingBean);


//-------------------------------------------------------------------------
// Delegate methods for resolving injection points
//-------------------------------------------------------------------------

//销毁参数中指定的bean,同时调用此Bean上的DisposableBean和DestructionAwareBeanPostProcessors方法
<T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;

//查找唯一符合指定类的实例,如果有,则返回实例的名字和实例本身
Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName) throws BeansException;

//查找唯一符合指定类的实例,如果有,则返回实例的名字和实例本身
Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException;

}

ListableBeanFactory

提供一次性获取当前BeanFactory 所有bean信息能力

​ ListableBeanFactory实现了BeanFactory接口, Listable意思是可列表的,ListableBeanFactory可以枚举它们的所有bean信息,而不用一个个通过bean的名称或类型一个个查找 (比如通过bean类型获取所有的bean) 。如果容器是有层级的,比如实现了HierarchicalBeanFactory接口,返回值不考虑层级的信息,只读取当前容器定义的信息

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
public interface ListableBeanFactory extends BeanFactory {

//判断是否包含指定名称的BeanDefinition
boolean containsBeanDefinition(String beanName);

//获取BeanDefinition的数量
int getBeanDefinitionCount();

//获取所有BeanDefinition的名称
String[] getBeanDefinitionNames();


//获取指定类型的所有Bean的名称,包括子类
//通过bean 定义或者FactoryBean的getObjectType判断.
String[] getBeanNamesForType(Class<?> type);

//获取指定类型的所有Bean的名称,包括子类
//通过bean 定义或者FactoryBean的getObjectType判断.
//includeNonSingletons 是否只要单例
//allowEagerInit 是否初始化懒加载的单例,FactoryBean初始化的类和工厂方法初始化的类.就是说执行这个方法会执行对应的初始化.
String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);

// 根据类型(包括子类)返回指定Bean名和Bean的Map
<T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;

//根据类型(包括子类)返回指定Bean名和Bean的Map
//includeNonSingletons 是否只要单例
//allowEagerInit 是否初始化懒加载的单例,FactoryBean初始化的类和工厂方法初始化的类.就是说执行这个方法会执行对应的初始化.
<T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
throws BeansException;

//获取注解类型的Bean
String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);

// 找到使用注解的类
//并放在指定Bean名和Bean的Map
Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;

//查找一个类上的注解,如果找不到,父类,接口使用注解也算.
// 根据指定Bean名和注解类型查找指定的Bean
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
throws NoSuchBeanDefinitionException;

}


HierarchicalBeanFactory

HierarchicalBeanFactory继承BeanFactory并扩展使其支持层级结构 (对BeanFactory提供分层)

1
2
3
4
5
6
7
8
public interface HierarchicalBeanFactory extends BeanFactory {

//返回本Bean工厂的父工厂
BeanFactory getParentBeanFactory();

//判断本地工厂是否包含这个Bean(忽略其他所有父工厂)。这也是分层思想的体现
boolean containsLocalBean(String name);
}

ConfigurableBeanFactory

​ ConfigurableBeanFactory继承了HierarchicalBeanFactory, SingletonBeanRegistry两个接口。定义了一些对BeanFactory的配置功能,比如通过addBeanPostProcessor配置Bean后置处理器setParentBeanFactory设置双亲Ioc容器

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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
String SCOPE_SINGLETON = "singleton";//单例
String SCOPE_PROTOTYPE = "prototype";//原型

/**
* 设置容器的父容器,获取父容器方法在父接口HierarchicalBeanFactory里
*/
void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;

/**
* 设置和获取类加载器,主要用于加载Bean,默认是线上上下文的loader
*/
void setBeanClassLoader(@Nullable ClassLoader beanClassLoader);
@Nullable
ClassLoader getBeanClassLoader();

/**
* 设置获取临时类加载器
*/
void setTempClassLoader(@Nullable ClassLoader tempClassLoader);
@Nullable
ClassLoader getTempClassLoader();

/**
* 设置是否缓存给定BeanDefinition和确定Bean类型的元数据,默认是开启状态.
* 关掉flag缓存会启用beanDefinition对象的热刷新.任何bean实例的创建都将重新查询bean class loader来确定这个Bean最新的类型
*/
void setCacheBeanMetadata(boolean cacheBeanMetadata);
boolean isCacheBeanMetadata();

/**
* 为beanDefinition值中的表达式提供解决策略.默认的BeanFactory里是没有激活的表达式支持的.
* 一个ApplicationContext通常会设置一个标准的表达式策略,以一种统一的EL兼容风格支持“#{}”表达式.
*/
void setBeanExpressionResolver(@Nullable BeanExpressionResolver resolver);
@Nullable
BeanExpressionResolver getBeanExpressionResolver();

/**
* 设置和获取ConversionService接口,进行数据类型转换
* @param conversionService
*/
void setConversionService(@Nullable ConversionService conversionService);
@Nullable
ConversionService getConversionService();

/**
* 添加一个PropertyEditorRegistrar应用于所有bean的创建过程.
* 一个Registrar创建了一个新的PropertyEditor实例,并且会将他们注册到一个给定的Registry中,并尝试刷新每个bean的创建.
* 这就避免了自定义Editor的同步应用需求.因此通常更倾向于使用这个方法来代替registerCustomEditor.
*/
void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);

/**
* 为所有给定类型的属性注册一个给定的自定义属性编辑器.通常在factory配置期间被调用.
* 注意这个方法注册一个共享的自定义属性编辑器实例;为了线程安全,需要授权该实例去进行同步操作.
* 通常更倾向于使用addPropertyEditorRegistrar来代替这个方法,这就避免了自定义编辑器同步的需要
*/
void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);

/**
* 使用一个已经在BeanFactory里注册过的自定义属性编辑器来初始化给定的PropertyEditorRegistry.
*/
void copyRegisteredEditorsTo(PropertyEditorRegistry registry);

/**
* 设置或获取自定义的类型转换器,BeanFactory用它来对Bean的属性值,构造参数等进行转换.这将会覆盖默认的PropertyEditor机制,
* 因此,使用无关的自定义Editor或自定义Editor Registrars.因为TypeConverter通常不是线程安全的,所以每次调用都会产生一个新的实例.
* 如果默认的PropertyEditor机制被激活,获取typeConverter方法将会返回所有已被注册的自定义的typeConverter
*/
void setTypeConverter(TypeConverter typeConverter);
TypeConverter getTypeConverter();

/**
* 用来增加一个嵌入式的StringValueResolver,比如说注解的属性.可以参考SpringMVC中的ArgumentResolver.
*/
void addEmbeddedValueResolver(StringValueResolver valueResolver);

/**
* 确定是否有一个嵌入式的value resolver已经在这个bean factory中注册了,并且可以通过resolveEmbeddedValue函数来应用.
*/
boolean hasEmbeddedValueResolver();

/**
* 决定一个给定的嵌入式的值,例如注解中的属性
*/
@Nullable
String resolveEmbeddedValue(String value);

/**
*添加一个新的BeanPostProcessor,通过这个工厂所创建的beans将会应用这个后置处理器.
* 在工厂的配置期间调用.注意这里的Post-processor提交将会按着registration的顺序被依次应用.
* 任何通过Ordered这个接口所实现的顺序语义将会被忽略.也要注意到自动检测的后置处理器将会在以编程方式注册的那些后置处理器之后执行.
*/
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);

//获取已经注册的Bean后置处理器的个数
int getBeanPostProcessorCount();

/**
*注册一个给定的scope,支持Scope的实现类.
*/
void registerScope(String scopeName, Scope scope);

/**
* 返回所有当前注册过的scope的名字.这个方法只返回明确注册过的scope的名字,内置的(Built-in)scopes像”singleton”和”prototype”不会被暴露.
* 如果没有返回的是空数组.
*/
String[] getRegisteredScopeNames();

/**
* 如果有的话,返回给定名字的Scope实现.和上一个函数一样,将只返回明确注册过的scope,内置的(Built-in)scopes像”singleton”和”prototype”不会被暴露.
*/
@Nullable
Scope getRegisteredScope(String scopeName);

/**
* 提供一个与这个工厂相关的安全的访问控制上下文.这个绝不会为空.
*/
AccessControlContext getAccessControlContext();

/**
* 从给定的工厂中拷贝所有相关的配置信息.应该包括了所有标准的配置,也包括了BeanPostProcessor,Scopes和factory-specific内置的一些配置.
* 应该不包括任何真实Bean的metadata信息,像BeanDefinition对象和bean的别名等
*/
void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);

/**
* 给定一个bean的名字,创建它的别名.这个方法的典型应用是支持那些在XML的ids里是无效的名字(被用于Bean的命名).
* 通常都是在factory的配置期间被调用,但是也可以用于别名的registration的运行时.所以一个实现了该函数的接口应该同步别名访问.
*/
void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException;

/**
* 处理所有目标名称的别名和在这个工厂注册过的别名,然后为它们应用给定的StringValueResolver.
* 这个value resolver是处理像目标bean名称甚或在别名名称里的占位符而设置的.
*/
void resolveAliases(StringValueResolver valueResolver);

/**
* 返回一个给定名字的合并后的BeanDefinition,如果有必要会将子BeanDefinition和父BeanDefinition进行合并.
* 并且也会考虑祖先容器中的BeanDefinition
*/
BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

//判断给定名字的Bean是否是一个FactoryBean.
boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException;

/**
* 设置Bean的当前创建状态
* @param beanName
* @param inCreation Bean是否正在创建中
*/
void setCurrentlyInCreation(String beanName, boolean inCreation);

boolean isCurrentlyInCreation(String beanName);

/**
* 为给定名称的Bean注册一个依赖Bean,并且该依赖Bean会在给定的Bean被销毁之前进行销毁
*/
void registerDependentBean(String beanName, String dependentBeanName);

/**
*如果有的话,返回依赖于给定名字Bean的所有Bean名称.
*/
String[] getDependentBeans(String beanName);

/**
* 如果有的话,返回给定名字Bean所依赖的所有Bean名称.
*/
String[] getDependenciesForBean(String beanName);

/**
* 依据BeanDefinition,销毁给定Bean的实例,(通常会从这个工厂中获取一个原型实例).
* 在销毁期间所抛出的任何异常都应该用捕获来取代往这个方法的调用者那里抛出.
*/
void destroyBean(String beanName, Object beanInstance);

/**
* 如果有的话,在当前目标Scope中销毁指定的ScopeBean.
* 在销毁期间所抛出的任何异常都应该用捕获来取代往这个方法的调用者那里抛出
*/
void destroyScopedBean(String beanName);

/**
* 销毁这个工厂中所有的singleton bean,包括一次性的已经注册的内嵌Bean.在工厂关闭的时候会被调用.
* 在销毁期间所抛出的任何异常都应该用捕获来取代往这个方法的调用者那里抛出.
*/
void destroySingletons();

ConfigurableListableBeanFactory

​ ConfigurableListableBeanFactory继承了ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory。在ConfigurableBeanFactory的基础上,并扩展了忽略依赖,自动装配判断,冻结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
public interface ConfigurableListableBeanFactory extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {

//在装配的时候忽略指定的依赖类型
void ignoreDependencyType(Class<?> type);

//在装配的时候忽略指定的接口
void ignoreDependencyInterface(Class<?> ifc);

//使用相应的自动装配值注册特殊依赖关系类型(ObjectFactory)。
void registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue);

//确定指定的bean是否有资格作为autowire候选者,注入到声明匹配类型依赖关系的其他bean中。
boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor) throws NoSuchBeanDefinitionException;

//返回指定bean的已注册BeanDefinition,允许访问其属性值和构造函数参数值(可以在bean工厂后处理期间修改)。
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

//返回所有bean名称的迭代对象
Iterator<String> getBeanNamesIterator();

//清除合并的bean定义缓存,删除尚未被认为有资格进行完整元数据缓存的bean条目。
void clearMetadataCache();

//冻结所有bean定义,表明注册的bean定义不会被修改或进一步后处理。
void freezeConfiguration();

//返回是否冻结此工厂的bean定义
boolean isConfigurationFrozen();

//确保所有非lazy-init单例都被实例化
void preInstantiateSingletons() throws BeansException;

}

AbstractBeanFactory


AbstractAutowireCapableBeanFactory


*DefaultListableBeanFactory


*Bean初始化的全过程


常见问题

Spring中有哪些方式可以把Bean注入到IOC容器

  • 使用xml文件的方式来定义bean,在spring启动的时候会解析这个xml,把bean装载到IOC容器
  • 使用@ComponentScan注解来扫描声明了 @Controller、@Service、@Component注解的类
  • 使用@Configuration注解声明配置类,并使用@Bean实现bean的定义
  • 使用@Import注解导入配置类或普通的Bean
  • 使用FactoryBean这一个工厂Bean来构建一个Bean的实例
  • 实现ImportBeanDefinitionRegistrat这个接口,可以动态注入bean实例
  • 实现ImportSelector接口。动态批量注入Bean对象

Spring为什么要用三级缓存来解决循环依赖

名称描述
singletonObjects一级缓存,存放完整的 Bean
earlySingletonObjects二级缓存,存放提前暴露的Bean,Bean 是不完整的,未完成属性注入和执行 init 方法
singletonFactories三级缓存,存放的是 Bean 工厂,主要是生产 Bean,存放到二级缓存中

什么是依赖注入(DI)?什么是控制反转(IOC)? 在 Spring 中,有几种依赖注入方式?

依赖注入:对象的创建过程由框架管理;对象外部资源的获取由对象本身反转到Ioc容器

控制反转

  • 控制:Ioc容器控制了对象;IOC容器控制对象的创建和外部资源的获取

  • 反转:对象的创建和外部资源的获取由程序本身反转到Ioc容器


spring的依赖注入有哪些方式

  • 变量注入: @Autowired
  • 构造器注入
  • set方法注入

Spring自动装配的方式

  • byName
  • byType
  • constructor
  • autodetect:首先尝试使用constructor来自动装配,如果无法工作,则使用byType方式

spring是如何创建一个Bean对象的

bean -> 推断构造函数 -> 反射生成对象 -> 依赖注入(属性填充)-> 初始化前(@PostConstruct) -> Aware接口 -> 初始化(InitializingBean)-> 初始化后(AOP)-> 代理对象 -> 放入一级缓存


Spring事务传播行为

传播属性描述
REQUIRED如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中(默认)
REQUIRES_NEW新建事务,如果当前存在事务,把当前事务挂起
SUPPORTS支持当前事务,如果当前没有事务,就以非事务方式执行
NOT_SUPPORTED不支持事务,如果当前存在事务就将事务挂起
MANDATORY使用当前的事务,如果当前没有事务,就抛出异常
NEVER不支持事务,如果当前存在事务,则抛出异常
NESTED如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与REQUIRED类似的操作

嵌套事务:(部分事务提交)内层事务的回滚不影响外层事务的提交


什么是单例池?作用是什么?

DefaultSingletonBeanRegistry#singletonObjects 这个 ConcurrentHashMap就是单例池

作用就是缓存单例bean对象


Bean对象和普通对象之间的区别是什么

区别:对象的创建流程不同,spring的bean创建包含了依赖注入,初始化前操作,初始化,初始化后操作(AOP)


推断构造方法是什么意思

spring 需要通过构造函数反射创建对象,这个时候就面临构造函数选择(如果有多个),默认使用无参构造函数

  • 如果没有无参构造函数并且有多个有参构造函数,则抛出异常(不知如何选择),除非给其中一个构造函数加@Autowired注解(暗示spring使用它)
  • 如果没有无参构造函数,并且只有一个有参构造函数,则使用它(没得选择)

单例Bean和单例模式之间有什么关系

单例bean:通过相同的依赖注入条件能获取到同一个对象,ioc容器能注册多个类型相同的单例bean.单例bean是相对依赖注入条件而言的

单例模式:整个JVM虚拟机中只允许存在这个类型的一个实例


什么是先bytype再byname

在构造函数注入中:假设在ioc容器中注册了多个类型相同的单例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
@Configuration
public class UserConfig {
@Bean
public SysUserEntity sysUserEntity() {
return new SysUserEntity().setUserId(1L);
}

@Bean
public SysUserEntity sysUserEntity2() {
return new SysUserEntity().setUserId(2L);
}

@Bean
public SysUserEntity sysUserEntity3() {
return new SysUserEntity().setUserId(3L);
}
}


@Service
public class UserService {

SysUserEntity sysUserEntity;

/**
* spring在ioc容器中能匹配到多个 SysUserEntity 实例,分别为
* name userId
* sysUserEntity userId = 1
* sysUserEntity2 userId = 2
* sysUserEntity3 userId = 3
* 那么再根据构造函数的形式参数名称判断,最终选择sysUserEntity2
* 这就是先bytype再byname
*/
public UserService(SysUserEntity sysUserEntity2) {
this.sysUserEntity = sysUserEntity;
}
}

Spring AOP底层是怎么工作的


Spring事务底层是怎么工作的


同类方法调用为什么会事务失效



spring
https://wugengfeng.cn/2022/03/23/spring/
作者
wugengfeng
发布于
2022年3月23日
许可协议