对Spring的理解

1、Spring IOC

ioc 叫做控制反转,也可以称为依赖注入( DI ),实际上依赖注入是 ioc 的另一种说法
控制翻转通俗解释
1 、谁控制谁 之前,是对象的创建和销毁由用户控制。而 ioc 是对象的创建和销毁就都交给了容
器进行控制。
2 、什么是反转 既然叫反转,肯定就有正转,正转其实就是对象去找实例,而反转就反过来了
嘛,让实例来找对象;
怎么找呢?当然是通过容器啦!

 

3 、谁依赖谁 spring 项目中, bean 对象的创建是依赖容器的,就好像孩子依赖父母一样,
孩子不能自己生出自己,需要父母的合作才能出生,这里的孩子就是 bean ,父母
就是容器;

 

4 、谁注入谁 通过容器注入了 bean 对象,而且这个过程是自动化的,也就是说容器会自动找到
bean

1.2 Spring Ioc

https://javaguide.cn/system-design/framework/spring/spring-knowledge-and-questions-sum
mary.html#component-%E5%92%8C-bean-%E7%9A%84%E5%8C%BA%E5%88%AB%E6%98%
AF%E4%BB%80%E4%B9%88

 

2、Spring IOC加载过程
首先通过 BeanDefinitionReader(bean 定义读取 ) (bean 低分内神锐的 ) 读取配置文件(什么 xml,
yml,properites结尾的文件)生产bean定义信息。
然后得到完整的bean定义对象( BeanDefinition bean 定义 低分内神 ) ,但是这是只是存储 bean 的定义
信息,还没有实例化对象(实例化就是 new 对象)
。这时只是像工厂生产一样,基本的原材料准备完成,但是还没有生产。这值原材料值的
BeanDefinition 生产值实例化对象。
之后在 BeanDefinition 到完整的 BeanDefinition 之间中间会有一个后置增强器,可以对 bean 的定义信
息进行修改 , 只要实现 BeanFactoryPostProcessor
(bean工厂后置处理器 bean fai可特瑞post普若塞萨)接口就行 。这个东西可以有多个只要实现接口就
行。
接下来,当获取到完整的 BeanDefinition 就可以创建对象,而这个创建的过程叫做 bean 的生命周期,
也就是从实例化到销毁的过程

 

2.1Spring Bean的生命周期

整体过程可以分为对象实例化,对象的初始化,使用,销毁

 

细化的流程为

 

 

按照顺序说
实例化对象
1、 postProcessBeforeInstantiation 方法 后处理前实例化 也就是实例化前置
通过实现 InstantiationAwareBeanPostProcessor 实例化感知Bean后处理器 ( 因死胆得 a e 外儿
beanpost 破儿萨骚 ) 接口,方法里有 2 个参数,分别是 beanClass beanName ,顾名思义,就是对在对
象实例化之前对 bean 对象的 class 信息进行修改或者扩展,以达到我们想要的功能,它的底层是动态代
AOP 技术实现的;且是 bean 生命周期中最先执行的方法;
2、 doCreateBean () 方法 doCreateBean 方法创建实例,用反射技术创建,只是相当于 new 了一个对
象出来而已,但这个时候只是将对象实例化了,对象内的属性还未设置;
3 postProcessAfterInstantiation 方法 后处理后实例化 也就是实例化方法 在目标对象实例
化之后调用,这个时候对象已经被实例化,但是该实例的属性还未被设置,都是 null
4 postProcessAfterInstantiation 方法 后处理属性值 属性修改 此方法可对属性值进行修改,修改范
围包括添加、修改、删除操作;如果实例化后置 返回值为 false 则不调用该方法
初始化( AOP 是在这里被注册的 5、给用户属性赋值 用户属性指的是用spring 的人自定义的bean对象属性,像 User、Student、
Teacher 、UserService、IndexService 这类的对象都是自定义bean对象,第5步主要给这类属性进行
赋值操作,使用的是 AbstractAutowireCapableBeanFactory.populateBean()(怕piu类特bean方
法) 方法进行赋值;
6、给容器属性赋值 容器属性其实就是容器自带的属性可以通过 Aware ( 饿外耳 ) 接口的实现类 类型
setBeanName setBeanFactory
7 、初始化前置 postProcessAfterInitialization 后处理后初始化 在每一个 Bean 初始化之前执行的方法
(有多少 Bean 调用多少次)
8 执行初始化方法 初始化方法有三个,分别是 添加了 @PostConstruct 注解的方法、实现
InitializingBean 接口、在 @bean 注解上添加 initMethod 属性;
bean 对象内添加 @PostConstruct 注解后即可实现初始化的功能,被 @PostConstruct 修饰的
方法会在构造函数之后, init() 方法之前运行。 有多个则会执行多次;
实现 InitializingBean 接口 是在 BeanFactory 完成属性设置之后 , 执行自定义的初始化行为。
@bean 注解上添加 initMethod 属性 bean 配置文件属性 init-method 用于在 bean 初始化时指
定执行方法,用来替代继承 InitializingBean
9 @PostConstruct 注解
10 、实现 InitializingBean 接口
11 @bean 注解上添加 initMethod 属性
12 、初始化后置 postProcessAfterInitialization() 在每一个 Bean 初始化之后执行的方法(有多少 Bean
调用多少次)
使用
13、使用中 到这一步, bean 对象就已经完全创建好了,是一个完整对象了,并且正在被其他对象使用
了;
销毁
spring 容器管理的 bean 默认是单例的 。默认在类上面有个 @ Scope (value =
ConfigurableBeanFactory .SCOPE_SINGLETON) 如果要设置成多例,只需要把 @Scope 的属性值
改成 @ Scope (value = ConfigurableBeanFactory .SCOPE_PROTOTYPE) 就行。 多例模式也叫
原型模式,它底层不是重新创建一个 bean 对象出来,而是使用深拷贝技术实现的,就是复制一个对象
出来进行使用
剩余的生命周期由用户控制
14.2 单例模式下销毁 会先执行 DisposableBean.destroy() 方法,然后在执行 destroy-Method 方法
15 、原型模式下的销毁 因为多例模式下, spring 无法进行管理,所以将生命周期交给用户控制,用户
用完 bean 对象后, java 垃圾处理器会自动将无用的对象进行回收操作; 通俗点说
首先spring bean生命周期分为4个部分。分别为实例化、初始化、使用、销毁四个部分。其中又可以
细分为15个部分。先说实例化部分。首先通过 实例化感知Bean后处理器接口
InstantiationAwareBeanPostProcessor )的中的 实例化前置方法。 在执行 对象的实例化方法
doCreateBean() 之后再执行 实例化后置方法 以及 属性修改方法。 在实例化前置方法中会传入两个
参数 分别是 beanClass beanName 根据名称就可以看成是对在对象实例化之前对 bean 对象的 class
息进行修改或者扩展,以达到我们想要的功能。在对象的实例化方法中,通过 doCreateBean 方法使用
反射的方法来实现实例的创建。这个时候只是 new 了一个对象,对象只是实例化了,对象内的属性还未
设置。在执行实例化后置方法中根据饭返回值在判断是否进入属性修改方法。因为根据代码得到,返
false 会忽略属性修改方法。在属性修改方法中 此方法可对属性值进行修改,修改范围包括添加、修
改、删除操作。以上便是我 spring bean 生命周期中实例化的部分的理解。
接下来说一下初始化。实例化过程中会执行先执行 给用户属性赋值方法 ( populateBean() ) 给用户属性赋
值。之后通过实现 给容器属性赋值接口 Aware 接口的实现类 实现给容器属性赋值。然后在执行 初始化
前置 以及 初始化后置方法。 在它们中会 执行初始化方法。初始化方法有三个添加了 @PostConstruct
注解的方法、实现 InitializingBean 接口、在 @bean 注解上添加 initMethod 属性; 这个地方我认为比
较重要的是初始化的三个方法我说下我的理解。 添加 @PostConstruct 注解的方法: bean 对象内添
@PostConstruct 注解后即可实现初始化的功能,被 @PostConstruct 修饰的方法会在构造函数之后,
init() 方法之前运行,有多个则会执行多次; 实现 InitializingBean 接口
InitializingBean.afterPropertiesSet() spring 初始化方法之一,作用是在BeanFactory完成属性设置
之后,执行自定义的初始化行为。执行顺序:在initMethod之前执行,在@PostConstruct之后执行;
@bean 注解上添加 initMethod 属性 init-method bean 配置文件属性 init-method 用于在 bean 初始
化时指定执行方法,用来替代继承 InitializingBean 接口;
接下来是使用和销毁。使用没啥说的 bean 完全创建好了,是一个完整对象了,并且正在被其他对象使
用了。而销毁分为两个部分:一部分为单例模式下,一部分为多例模式, 多例模式也叫原型模式,它
底层不是重新创建一个 bean 对象出来,而是使用深拷贝技术实现的,就是复制一个对象出来进行使用
如果是单例模式,会先执行 DisposableBean.destroy() 方法,然后在执行 destroy-Method 方法
如果是多例模式下, spring 无法进行管理,所以将生命周期交给用户控制,用户用完 bean 对象后, java
垃圾处理器会自动将无用的对象进行回收操作;
3、String Aop
AOP 面向切面编程能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、
日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来
的可拓展性和可维护性。
Spring AOP 会使用 JDK Proxy,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK
Proxy 去进行代理了,这时候 Spring AOP 会使用 Cglib 生成一个被代理对象的子类来作为代理 Spring AOP动态代理主要有两种方式,JDK动态代理和CGLIB动态代理。
JDK 动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。 JDK 动态代理的核心是
InvocationHandler 接口和 Proxy 类。
如果目标类没有实现接口,那么 Spring AOP 会选择使用 CGLIB 来动态代理目标类。 CGLIB Code Generation
Library ),是一个代码生成的类库,可以在运行时动态的生成某个类的子类(通过修改字节码来实现代理)。
注意, CGLIB 是通过继承的方式做的动态代理,因此如果某个类被标记为 final ,那么它是无法使用 CGLIB 做动态
代理的。 jdk cglib 动态代理来共同实现我们的 aop 面向切面的功能。
https://juejin.cn/post/6844903762025250824

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值