Spring学习记录

本文详细探讨了Spring框架的各个核心概念,包括Bean的生命周期、依赖注入、配置类的作用、事务管理、Bean的创建方式、扫描过程以及源码分析。讲解了从Bean的实例化到初始化的全过程,涉及InstantiationAwareBeanPostProcessor、Autowired、InitializationBean等多个关键接口。还深入研究了Spring如何解决循环依赖,并解析了Spring启动过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring学习

Spring学习第一天

  • Spring Bean 创建的过程
    一个对象->通过构造方法->得到一个对象->通过依赖注入进行属性赋值(byType/byName,先通过type找,找到多个在根据name找,如果还是存在多个,则报错)->初始化前->初始化->初始化后(AOP在这个步骤实现)->Bean(如果经过了AOP处理,生成的Bean则是代理Bean)

  • 初始化前,初始化,初始化后的扩展方法

    1. @PostConstruct
    2. InitializationBean
  • 事务失效问题
    事务失效主要看调用标记@Transactional方法是被普通bean调用还是代理bean调用

  • @Configuration的作用
    被此注解标记后,配置类就成为一个代理类,当要创建bean时,会先从spring容器判断是否存在此类,存在则直接返回,不会重复创建。

Spring学习第二天

  • 首先明确一点:
    ApplicationContext ac = new XXXApplicationContext(xxx);
    ac.getbean
    单例,非懒加载的bean在第一行代码中就会创建;反之,在第二行创建

  • 手写spring实现大概步骤

  1. 读取配置,得到扫描路径

  2. 通过类加载器获取路径->转换成File->转换成Class

  3. 通过class.isAnnotationPresent(@Compoment.class) 判断此类是否需要被Spring容器管理

  4. 转换成BeanDifinition,放入Map(避免重复解析)
    以上,就完成了bean的扫描,接下来开始创建bean

  5. 对于单例可以直接通过构造方法创建,放进单例池 ;对于多例,每次getBean的时候都创建
    以上就完成了bean的实例化,接下来实现依赖注入

  6. 通过class.getDeclareFile().isAnnotationPresent(Autowired.class)判断是否需要进行依赖注入

  7. 接下来实现初始化,初始化前,初始化后
    初始化可以使用InitializationBean测试
    初始化前和初始化后可以使用BeanPostProcessor测试
    初始化前可以使用BeanNameAware测试
    初始化后可以先使用动态代理实现模拟切面实现

Spring学习第三天

  • 创建bean的方式:声明式,编程式

  • 几个常用的解析Bean成beanDefinition的类
    AnnotatedBeanDefinitionReader/ClassPathXXX 父类 GenericXXX
    XmlBeanDefinitionReader

  • ApplicationContext与BeanFactory的区别
    国际化/资源加载/获取运行时环境/事件发布

  • DefaultListableBeanFactory

  • BeanFactory和FactoryBean的区别
    BeanFactory生成的bean是经过了完整的生命周期的,而FactoryBean创建的声明周期只经历了初始化后(考虑到AOP,其他步骤不需要经历是因为自己可以定制化)
    2.会创建2个bean,一个是通过@Component创建出来的,放在单例池,一个是getObject方法返回的,放在另外一个缓存里面
    3.得到的bean变成getObject返回的bean

Spring学习第四天

  • 主要学习spring源码中
  1. 扫描的过程
  2. 创建单例、非懒加载的bean
  3. @Conditional,@LookUp
  4. SmartInitializingSingle:在所有的单例非懒加载的bean创建完成之后被调动
  5. 并不是所有的bean都是首字母小写
  • 入口
  1. 扫描:ClassPathBeanDefinitionScanner.scan(xxx)
  2. 创建单例、非懒加载的单例bean:
    org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
  • 合并BeanDefinition
    当一个bean存在父子关系时使用

Spring学习第五天

  • 主要学习bean生命周期每个阶段重要的接口
  1. 实例化前 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()

  2. 实例化

  3. MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()

  4. 实例化后 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()

  5. InstantiationAwareBeanPostProcessor.postProcessPropertyValues() // @Autowired,@Resource,@Value就是这个方法里面被解析的
    AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor

  6. Aware回调 ApplicationContextAwareProcessor

  7. 初始化前

  8. 初始化

  9. 初始化后

Spring学习第六天

主要学习Spring是怎么解决循环依赖
解决Spring循环依赖使用了三级缓存,包括singletonObjects、earlySingletonObjects
、singletorFactories

  • 以A,B出现循环依赖为例

    1. 标记A为创建中
    2. 实例化A(得到原始对象,放入creatingSet中)—>放入三级缓存singleFactories(beanName,()->getEarlyBeanReference(beanName,mbd,bean)); 黑体部分逻辑主要用于判断是否需要AOP,需要则返回代理对象,不需要则返回原始b对象
    3. 填充B(单例池没有—>实例化B)
    4. 填充A(发现creatingSet中有,出现循环依赖)
    5. 去earlySingletonObjects找,没有
    6. 去singletorFactories 找,执行getEarlyBeanReference(beanName,mbd,bean)放入二级缓存(此时放入的还是半成品,还没有经历完整的生命周期)
    7. 填充属性等完整生命周期

    二级缓存的作用和意义:
    作用:存半成品,保存还未经历完整生命周期的对象
    意义:保证单例
    三级缓存的作用和意义:
    作用:保存表达式判断是否需要AOP
    意义:打破循环依赖
    思考: 如果不考虑AOP,那么二级缓存就可以解决循环依赖

Spring学习第七天

主要学习Spring启动过程源码分析

public AnnotationConfigApplicationContext(Class<?>… annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
对于此方法第一步主要是初始化一些重要的类,做一些提前准备
第二步主要是将配置转换成BeanDefinition,放入beanDefinitionMap

理解refresh()的含义

BeanFactoryPostProcessor:表示BeanFactory的后置处理器,用来对BeanFactory进行加工的
BeanPostProcessor:表示Bean的后置处理器,是用来对Bean进行加工的

### 关于Spring框架的学习教程和笔记 #### Spring框架的核心概念与组件介绍 Spring是一个分层架构,通过使用基本的Java Bean来完成以前只有EJB才能实现的功能。它提供了对面向切面编程的支持,允许用户定义方法拦截器,在特定的方法调用前后执行通知逻辑[^1]。 #### Web开发中的Spring应用实例 对于Web应用程序而言,`spring-web-5.3.24.jar` 和 `spring-webmvc-5.3.24.jar` 是必不可少的部分。前者提供了一个全面的、易于使用的HTTP请求处理机制;后者则实现了MVC设计模式下的控制器接口,使得开发者可以更方便地构建动态网站。 #### 使用Maven搭建Spring项目实践指南 当采用Maven作为项目的构建工具时,可以通过编辑POM文件快速引入所需的库文件。例如,为了开启web场景支持,只需简单添加如下依赖项即可: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> ``` 这段XML片段会自动下载并配置好所有必要的jar包,从而简化了环境设置过程[^3]。 #### 配置服务发现与外部化配置管理方案 针对分布式系统的复杂需求,还可以考虑集成Consul来进行服务注册和服务发现工作,并利用Bootstrap上下文提前加载全局共享属性。这通常涉及到向pom.xml中追加额外的服务端点连接信息: ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> </dependency> ``` 上述代码段有助于提高微服务体系结构下各节点之间的协作效率[^4]。 #### 数据验证功能的具体实施方式 最后,在实际编码过程中如果遇到表单提交等涉及输入合法性判断的情况,则可借助Hibernate Validator API轻松搞定。创建一个名为ValidationConfig.java的新类用于初始化默认校验工厂对象LocalValidatorFactoryBean: ```java @Configuration @ComponentScan("com.atguigu.spring6.validation.method2") public class ValidationConfig { @Bean public LocalValidatorFactoryBean validator() { return new LocalValidatorFactoryBean(); } } ``` 此段程序展示了如何自定义配置以增强业务逻辑层面的数据完整性保护措施[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值