本文不分析Spring的源码流程,只是介绍一些基础的概念,在阅读源码之前,我们应该首先明确研究的对象是什么,才能有的放矢。

Spring作为BeanFactory, 和现实工厂有着许多类似之处。

需要各种原料Class,存在各个jar包内,jar包内又分为不同的Package。

每一种原料有相应的说明书------BeanDefinition

需要存储说明书的地方 BeanDefinitionRegistry

需要搬运工:BeanFactoryPostProcessor

需要按照说明书生产零件   newInstance .

各种零件    Singleton

半成品       BeanWrapper

成品    ExposedObject

零件和零件之间有依赖关系  Dependency

需要存储零件的地方

存储半成品的地方

需要存储成品的地方

需要各种工序Processor

需要决定Processor如何执行的地方PostProcessorRegistrationDelegate,

需要有存储工序的地方

需要对零件进行组装    AutowireCapableBeanFactory, 这部分也就是注入依赖的过程。

需要对成品的一些功能进行增强。  对Method进行增强。

顺着这条线看应该会容易很多。

1: BeanDefinition     一个Class对应一个BeanDefinition,有了BeanDefinition再构建instance。

可以理解为Class可以分为不同的功能。

1.1   普通的bean

1.2   能处理@Component的bean

1.3   能处理@Configuration的bean

ConfigurationClassBeanDefinition  , 对应@Configuration 修饰的Class类。     ConfigurationClassBeanDefinitionReader 是负责分析ConfigurationClass。

spring 里面有一个非常常见的变量 mbd,   意为getMergedLocalBeanDefinition 。

BeanDefinition 其实是相当复杂的一个类,需要考虑到Bean的各种可能潜在的属性以及整个生命周期。

@Nullable
private volatile Object beanClass;     代表的class
@Nullable
private String scope;                    作用域
private boolean abstractFlag;            是否是abstract类
private boolean lazyInit;                是否是懒加载
private int autowireMode;                autowireMode         
private int dependencyCheck;             是否检查依赖
@Nullable
private String[] dependsOn;               依赖那些其他的beanClass
private boolean autowireCandidate;        候选人
private boolean primary;                  是否是主类
private final Map<String, AutowireCandidateQualifier> qualifiers;        限定    
@Nullable
private Supplier<?> instanceSupplier;      供应商
private boolean nonPublicAccessAllowed;    
private boolean lenientConstructorResolution;    宽容的
@Nullable
private String factoryBeanName;
@Nullable
private String factoryMethodName;
@Nullable
private ConstructorArgumentValues constructorArgumentValues;        构造方法的参数
@Nullable
private MutablePropertyValues propertyValues;    属性
@Nullable
private MethodOverrides methodOverrides;        
@Nullable
private String initMethodName;        init方法
@Nullable
private String destroyMethodName;    销毁方法的名称
private boolean enforceInitMethod;
private boolean enforceDestroyMethod;
private boolean synthetic;        是否是人工合成的
private int role;                   角色
@Nullable
private String description;        描述
@Nullable
private Resource resource;         class文件的位置
@Nullable
private BeanDefinitionHolder decoratedDefinition;
@Nullable
private AnnotatedElement qualifiedElement;
boolean allowCaching = true;
boolean isFactoryMethodUnique = false;
@Nullable
volatile ResolvableType targetType;
@Nullable
volatile Class<?> resolvedTargetType;       // resolvedTargetType 目标类型目标类型
@Nullable
volatile ResolvableType factoryMethodReturnType;
@Nullable
volatile Method factoryMethodToIntrospect;                 
final Object constructorArgumentLock = new Object();
@Nullable
Executable resolvedConstructorOrFactoryMethod;
boolean constructorArgumentsResolved = false;
@Nullable
Object[] resolvedConstructorArguments;
@Nullable
Object[] preparedConstructorArguments;
final Object postProcessingLock = new Object();
boolean postProcessed = false;
@Nullable
volatile Boolean beforeInstantiationResolved;
@Nullable
private Set<Member> externallyManagedConfigMembers;
@Nullable
private Set<String> externallyManagedInitMethods;
@Nullable
private Set<String> externallyManagedDestroyMethods;

能将事物的本质描述清楚实在是不容易。

2:既然有BeanDefinition ,那么就需要有存放BeanDefinition的地方(容器) ,  称为BeanDefinitionRegistry

beanDefinitionMap 就是存放BeanDefinition的地方。  Map<String,BeanDefinition>

定义增删查等基本操作。

public interface BeanDefinitionRegistry extends AliasRegistry {
void registerBeanDefinition(String var1, BeanDefinition var2) throws BeanDefinitionStoreException; void removeBeanDefinition(String var1) throws NoSuchBeanDefinitionException; BeanDefinition getBeanDefinition(String var1) throws NoSuchBeanDefinitionException; boolean containsBeanDefinition(String var1); String[] getBeanDefinitionNames(); int getBeanDefinitionCount(); boolean isBeanNameInUse(String var1);
}

除此之外还可以给BeanDefinition起一个别名。

3:Singleton

public interface SingletonBeanRegistry {
void registerSingleton(String var1, Object var2); @Nullable
Object getSingleton(String var1); boolean containsSingleton(String var1); String[] getSingletonNames(); int getSingletonCount(); Object getSingletonMutex();
}

很明显Singleton全部为Object类型,这意味着在@Autowired 注入依赖时,需要进行类型转换。 注意这里没法进行进行强制类型转换。 这也是spring推荐

使用构造方法注入依赖的原因吧,   类型擦除之后还得再还原原始类型,很复杂。

Singleton  分为两种:

3.1:    不依赖其他Singleton的Singleton

3.2:    依赖其他Singleton的Singleton

存放Singleton的地方

4: ScopedObject

存放 ScopeObject的地方

5:Bean

从功能来看:  Bean分为NamedBean DisposableBean  InitializingBean 和 FactoryBean<T>

6:BeanWrapper

7:存放Singleton和Scope,以及对他们进行加工改造的地方称为BeanFactory  , 实际上Singleton存储在SingletonBeanRegistry ,Scope存在

RequestContextHolder 中,BeanFactory 提供了桥接入口

FactoryBean和BeanFactory 的区别,   FactoryBean<T> 带有参数T , FactoryBean 只是生产T对应的BeanDefinition

FactoryBean的作用:  有些Bean能够直接通过newInstance 直接构建,有些Bean需要通过反射进行构建,比如@Mapper,@Feign ,@Repository    修饰的

interface 。这些接口需要通过FactoryBean解析,bangding相应的MethodHandler,  然后注入到BeanDefinition。 注意此时只是注册到BeanDefinition。

8:BeanInstance

9: BeanFactoryPostProcessor       这命名真让人误解

FactoryBean 不能自己注入到spring中去,需要BeanFactoryPostProcessor才能注入到spring中去。

10: BeanPostProcessor

11:   InstantiationStrategy

12: proxy

13: Interceptor

下面介绍一下Processor

了解一两个Processor会对Bean的加工过程有所了解。  个人感觉这种模式和pipeline模式很像。

Processor 没法自行启动,需要委托给 PostProcessorRegistrationDelegate 进行启动。

Processor 的执行有先后顺序关系。

对于BeanFactoryPostProcessor 而言                registryProcessors  >  regularPostProcessors

对应BeanPostProcessor而言

priorityOrderedPostProcessors >  orderedPostProcessorNames > nonOrderedPostProcessorNames  > internalPostProcessors

和Aop相关的Processor

所有Processor接口的子类,

BeanFactoryProcessor接口的子类也十分多。

最后介绍一个超级大Boss    DefaultListableBeanFactory

整个BeanFactory的继承体系也十分庞大。

spring 最终注入依赖的地方

InjectionMetadata
protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs) throws Throwable {
if (this.isField) {
Field field = (Field)this.member;
ReflectionUtils.makeAccessible(field);
field.set(target, this.getResourceToInject(target, requestingBeanName));
} else {
if (this.checkPropertySkipping(pvs)) {
return;
} try {
Method method = (Method)this.member;
ReflectionUtils.makeAccessible(method);
method.invoke(target, this.getResourceToInject(target, requestingBeanName));
} catch (InvocationTargetException var5) {
throw var5.getTargetException();
}
}
}

程序架构设计应该不只是顺序思维,更应该锻炼立体思维,思前顾后,承上启下,注重接口和继承体系的设计,还应该掌握一些基础基本的专业术语,设计模式。

你应该明确自己研究的对象,怎么描述它,怎么构建它,怎么增强它,怎么存储它,以及怎么使用它。

与AOP相关的概念

Advide 。

Advisor

Spring BeanFactory和现实工厂的对比的更多相关文章

  1. Spring - BeanFactory 新旧工厂差异

    在将要被加入到spring容器中的service中,添加static静态代码块(加载类时被调用),用于判断spring中新旧bean工厂的加载性质. package com.witwicky.serv ...

  2. spring BeanFactory及ApplicationContext中Bean的生命周期

    spring bean 的生命周期 spring BeanFactory及ApplicationContext在读取配置文件后.实例化bean前后.设置bean的属性前后这些点都可以通过实现接口添加我 ...

  3. Spring BeanFactory与FactoryBean的区别及其各自的详细介绍于用法

    Spring BeanFactory与FactoryBean的区别及其各自的详细介绍于用法 1. BeanFactory BeanFactory,以Factory结尾,表示它是一个工厂类(接口),用于 ...

  4. Spring BeanFactory 与 FactoryBean 的区别

    BeanFactory 和 FactoryBean 都是Spring Beans模块下的接口 BeanFactory是spring简单工厂模式的接口类,spring IOC特性核心类,提供从工厂类中获 ...

  5. Spring中如何使用工厂模式实现程序解耦?

    目录 1. 啥是耦合.解耦? 2. jdbc程序进行解耦 3.传统dao.service.controller的程序耦合性 4.使用工厂模式实现解耦 5.工厂模式改进 6.结语 @ 1. 啥是耦合.解 ...

  6. Spring 源码(3)Spring BeanFactory 是怎么创建的?

    Spring创建 BeanFactory 的方式 按照Bean的配置方式手动创建可以分为两种: 使用XMl配置的Bean 这种方式使用xml配置文件配置Bean的信息并且设置扫描的路径,扫描到的包可以 ...

  7. XI.spring的点点滴滴--IObjectFactoryPostProcessor(工厂后处理器)

    承接上文 IObjectFactoryPostProcessor(工厂后处理器)) 前提是实现接口的对象注册给当前容器 直接继承的对象调用这个postProcessBeanFactory方法,参数为工 ...

  8. Spring BeanFactory实例化Bean的详细过程

    Spring中Bean的实例化是Bean生命周期的一个重要环节,通常Bean初始化后将不再改变. 那么Spring实例Bean的过程到底是怎么样的呢?!   要想获取到一个bean对象,得先通过Bea ...

  9. windows服务 MVC之@Html.Raw()用法 文件流的读写 简单工厂和工厂模式对比

    windows服务   public partial class Service1 : ServiceBase{ System.Threading.Timer recordTimer;public S ...

随机推荐

  1. QT绘制简易表盘

    1.简介 最近学习了一下QT,熟悉了一段时间后发现它的功能还是挺强大的,同时也比较方便用户上手去使用.现在就基于最近学习的内容,实现一个简易的带指针旋转功能的表盘.文中表盘的实现是基于QT的QPain ...

  2. 如何在TVM上集成Codegen(上)

    如何在TVM上集成Codegen(上) 许多常用的深度学习内核,或者提供DNNL或TensorRT等框架和图形引擎,让用户以某种方式描述他们的模型,从而获得高性能.此外,新兴的深度学习加速器也有自己的 ...

  3. TensorRT 7.2.1 开发概要(上)

    TensorRT 7.2.1 开发概要(上) Abstract 这个TysRR7.2.1开发者指南演示了如何使用C++和Python API来实现最常用的深层学习层.它展示了如何使用深度学习框架构建现 ...

  4. JVM-gcRoots 和 强引用,软引用, 弱引用, 虚引用, 代码演示和应用场景

    什么是垃圾? 什么是gcRoots, 谈谈你对 强, 软, 弱 , 虚引用的理解, 他们的应用场景 jvm采用可达性分析法: 从gcRoots集合开始,自上向下遍历,凡是在引用链上的对象,都不是垃圾, ...

  5. SQL注入问题------JDBC编写简单登录代码

    一.什么是sql注入 sql注入:用户输入的内容, 有一些sql的特殊关键字参与字符串的拼接,完成了一条逻辑发生变化的新的SQL语句 !用代码举个例子简单说明一下: package cn.zhbit. ...

  6. MySQL零散知识点(01)

    内容概要 --- 表字段操作补充(掌握) --- python操作MySQL(掌握) --- 视图(了解) --- 触发器(了解) --- 存储过程(了解) --- 事务(掌握) --- 内置函数(了 ...

  7. 为什么有些公司的IT很乱?

    --别问,问就是赛马,问就是KPI驱动 为什么很多公司甚至是闻名遐迩的资深IT公司,都被吐槽IT技术建设很烂呢?按惯例,问为什么之前,先问是不是. ▒壹·鹅厂▒ 2018年一个名为"当下腾讯 ...

  8. 「模拟8.29」chinese(性质)·physics·chemistry(概率期望)

    T1  chinese 根据他的问题i*f[i]我们容易联想到,答案其实是每种方案中每个点的贡献为1的加和 我们可以转变问题,每个点在所有方案的贡献 进而其实询问就是1-k的取值,有多少中方案再取个和 ...

  9. Redundant Paths 分离的路径

    Redundant Paths 分离的路径 题目描述 为了从F(1≤F≤5000)个草场中的一个走到另一个,贝茜和她的同伴们有时不得不路过一些她们讨厌的可怕的树.奶牛们已经厌倦了被迫走某一条路,所以她 ...

  10. Golang通过结构体解析和封装XML

    Golang解析和封装XML 解析XML成结构体Demo package main import ( "encoding/xml" "fmt" ) //我们通过 ...