spring系列

ApplicationContext就是IOC容器
@Bean是通过工厂方法或构造器创建的,和IOC容器不同,IOC容器是通过反射创建的。

SpringIOC容器初始化过程

1、Spring容器中的Bean默认都是单例的,但是并不是线程安全的,所有线程都共享一个单例Bean,因此存在资源竞争的关系。
但是在实际开发中,单例Bean一般是无状态的,线程之间的操作不会对Bean的成员执行除查询之外的操作,所以说是线程安全的,使用时只是调用Service、Dao的方法,并不会修改bean属性。
2、如何保证Spring容器中的Bean是线程安全的
1、默认的singleton单例的Bean改为prototype多例的Bean;
2、在Bean对象中避免定义可变的成员变量。
3、将Bean的可变成员变量保存在ThreadLocal中。
3、对Spring框架Bean的生命周期了解吗?
1、解析xml配置或注解的类,得到BeanDefinition
2、通过BeanDefinition反射创建Bean对象(实例化Bean对象)
3、对Bean对象进行属性填充
4、回调Aware接口的方法,比如BeanNameAware。
5、调用BeanPostProcessor的初始化前方法。
6、调用init初始化方法
7、调用BeanPostProcessor的初始化后方法,此处会进行AOP。
8、将创建好的Bean对象放入一个Map中。
9、业务中使用Bean对象就从Map中获取。
10、Spring容器关闭时调用DisposableBean的destroy方法销毁Bean对象。

Bean的生命周期 -五版本 Bean的生命周期 -五版本

0、根据@ComponentScan去扫描@@Component注解,然后去实例化。
1、实例化
a. 通过反射、推断构造函数的进行实例化
b. 实例工厂、静态工厂实例化Bean
2、依赖注入(给属性赋值)
解析自动装配(by name、by type、construct、@Autowired<先根据By type查询,如果找到多个再根据by name查询>)DI的体现
3、初始化
4、使用Bean
5、销毁Bean
Bean的生命周期 -七版本
1、实例化
2、依赖注入(给属性赋值)
3、初始化前BeanPostProcessor before方法
4、初始化
5、初始化后BeanPostProcessor after方法
6、使用Bean
7、销毁Bean

Bean的生命周期 -十版本 Bean的生命周期 -十版本

1、实例化
2、依赖注入(给属性赋值)
3、BeanNameAware、BeanFactoryAware方法执行
4、初始化前BeanPostProcessor before方法
5、InitialingBean接口的方法执行
6、初始化方法init()
7、初始化后BeanPostProcessor after方法(AOP的在此处)
8、使用Bean
9、DisposableBean接口的方法执行。
10、销毁Bean

详细版本

一、 SpringBoot中的自动装配原理

  1. @SpringBootApplication
  2. @EnableAutoConfiguration
  3. SpringFactoriesLoader读取MEAT-INF/spring.factories文件中的所有自动配置类(Java中的SPI思想)。
  4. 加载的配置类上会有条件注解进行过滤,没有导入jar包的不会被加载。
  5. ImportSelector接口将符合的Bean加入Spring容器中。
  6. 创建Bean的定义,BeanDefinition,比如类的包名、属性等信息。
  7. 实例化Bean对象,放入SpringIOC容器中。

二、IOC容器的初始化步骤

视频地址[https://www.bilibili.com/video/BV1gW411W7wy?spm_id_from=333.788.videopod.episodes&vd_source=73d100dec9413b936c0d6dc4e24a1168&p=49]()
  • AbstractApplicationContext.refresh
      • finishBeanFactoryInitialization
            • 开始:beanFactory.preInstantiateSingletons()
                  • 获取所有的单实例bean信息
                  • List beanNames = new ArrayList<>(this.beanDefinitionNames);
                  • 获取BeanDefinition的定义信息
                  • RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
                        • 判断当前的bd不是抽象&&是单实例的&&不是懒加载的
                              • 1、是工厂Bean
                              • 2、不是工厂Bean-》获取单实例bean,创建对象
                                    • 获取单实例bean

                                  • -1、Object sharedInstance = getSingleton(beanName);
                                  • -2、获取不到,开始Bean的创建流程
                                  • -#标记该bean已经被创建了,防止多线程调用
                                  • -3、markBeanAsCreated(beanName);
                                  • -#获取BeanDefinition的定义信息
                                  • -RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                                  • -#判断当前Bean是否有依赖的其他Bean
                              • -3、String[] dependsOn = mbd.getDependsOn();
                                如果有通过getBean创建其他的Bean(递归调用-回到开始的位置)
                                5、如果当前Bean是单实例bean,调用sharedInstance = getSingleton(beanName, () -> {
                                1、调用createBean(beanName, mbd, args);

                            调用部分beanPostProcessor(不是IOC容器的BeanPostProcess)

                            2、调用Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

                            创建bean

                            3、Object beanInstance = doCreateBean(beanName, mbdToUse, args);
                            #创建Bean实例
                            1、instanceWrapper = createBeanInstance(beanName, mbd, args);
                            2、通过工厂方法或构造器创建bean。

                            给Bean赋值

                            4、populateBean(beanName, mbd, instanceWrapper);
                            这里会调用一些BeanPostProcess方法====
                            #给属性赋值
                            1、applyPropertyValues(beanName, mbd, bw, pvs);
                            5、#初始化Bean
                            exposedObject = initializeBean(beanName, exposedObject, mbd);
                            #执行Aware方法《BeanNameAware、BeanClassLoaderAware、BeanFactoryAware》
                            1、invokeAwareMethods
                            #执行所有《BeanPostProcessorsBefore》方法
                            2、applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
                            #执行初始化方法
                            3、invokeInitMethods(beanName, wrappedBean, mbd);
                            1、《InitializingBean.afterPropertiesSet》初始化
                            #是否自定义了初始化方法init()
                            2、String initMethodName = mbd.getInitMethodName();
                            #执行所有《BeanPostProcessorsAfter》方法
                            4、wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
                            6、#Bean的销毁方法
                            registerDisposableBeanIfNecessary(beanName, bean, mbd);

Bean Factory和Factory Bean的区别

相同点:都是用来创建bean对象的,最终都会被spring来管理。

不同点:使用Bean Factory创建对象时,必须要遵循严格的生命周期流程,过程复杂,如果想要简单的自定义某个对象的创建,同时创建完成的对象想要交给spring管理,
需要实现Factory Bean接口
T getObject() throws Exception;
Class<?> getObjectType();
default boolean isSingleton()

Spring中的设计模式

单例模式:bean默认都是单例的
原型模式:指定作用域prototype
工厂模式:BeanFactory
模版模式:postProcessBeanFactory,onRefresh,AbstractBeanFactory
策略模式:XmlBeanDefinitionReader
观察者模式:listener,event
适配器模式:Adapter
装饰者模式:BeanWapper
责任链模式:使用aop的时候会先生成一个拦截器链
代理模式:动态代理
委托者模式:delegate

AOP的底层原理

aop是ioc的一个扩展功能,先有ioc,再有的aop,只是在ioc的整个流程中新增的一个扩展点而已,BeanPostProcess
总:
aop的应用场景:事务、日志
动态代理:jdk和cglib
分:bean的创建过程中有一个步骤可以对bean进行扩展实现,aop本身就是一个扩展功能,所以在BeanPostProcessAfter方法来进行实现。
1、代理对象的创建过程(advice,切面,切点)
2、通过jdk或者cglib的方式来生成代理对象
3、在执行方法调用的时候,会调用到生成的字节码文件中,直接会找到DynamicAdvisoredInterceptor类中的intercept方法,从此方法开始执行。
4、根据之前定义好的通知来生成拦截器链
5、从拦截器链中依次获取每一个通知开始进行执行,在执行过程中,为了方便找到下一个通知,会有一个CglibMethodInvocation的对象,从-1的位置依次开始查找并执行。

Spring事务如何回滚?(等价与Spring事务管理如何实现的)

总:spring的事务是由aop实现的,首先要生成具体的代理对象,然后按照aop的整套流程执行具体操作逻辑,正常情况下要通过通知来完成核心功能,
但是事务不是通过通知来实现的,而是通过TransactionInterceptor实现的,然后调用invoke实现具体逻辑。
分:
1、准备工作,解析各个方法上事务相关的属性,根据具体属性判断是否开始新的事务
2、当需要开启时,获取数据库连接,关闭自动提交功能,开启事务
3、执行具体的sql逻辑操作。
4、操作过程中,如果执行失败,通过completeTransactionAfterThrowing完成事务的回滚操作,回滚具体逻辑通过doRollBack方法实现的,实现时也要先获取连接对象,通过连接对象回滚。
5、操作过程中,如果执行成功,通过commitTransactionAfterReturning完成事务的提交操作,提交具体逻辑通过doCommit方法实现的,实现时也要获取连接,通过连接对象提交。
6、当事务执行完毕后,需要清除相关的事务信息cleanupTransactionInfo。

posted @ 2025-07-08 10:01  Charlie-Pang  阅读(10)  评论(0)    收藏  举报