spring

1.核心类-DefaultListableBeanFactory

https://blog.csdn.net/Taylar_where/article/details/90547570

2.核心类-XmlBeanDefinitionReader

 

3.生成Bean步骤

  • 根据配置文件,生成Resource(ResourceLoader)

  • 获取对xml文件的验证模式

  • 加载xml,得到document(DocumentLoader)

  • 注册bean

4.解析bean

  • <bean>元素和BeanDefinition属性一一对应

  • spring通过BeanDefinition将配置文件中的<bean>信息转换为容器的内部表示

  • 将BeanDefinition注册到BeanDefinitionRegistry中

  • 获取到的信息封装到BeanDefinitionHolder中,所以BeanDefinitionHolder中包含了各种信息,例如:class、name、id等

  • 对自定义标签进行解析

  • 发出相应事件,通知相关监听器bean加载完成

5.bean的加载

  • 尝试从缓存中获取bean(getSigleton)

  • 返回对应的实例(getObjectForBeanInstance)

  • 获取单例(getSigleton)

  • 创建bean(createBean)

6.FactoryBean

用户可以通过实现FactoryBean接口定制实例化bean的逻辑

FactoryBean的3个方法

  1. T getObject()返回创建的实例

  2. boolean isSingleton()是否单例

  3. Class<T> getObjectType() 返回创建的bean类型

7.ApplicationContext&BeanFactory

ApplicationContext:

应用上下文,继承BeanFactory接口,它是Spring的一各更高级的容器,提供了更多的有用的功能;

1) 国际化(MessageSource)

2) 访问资源,如URL和文件(ResourceLoader)

3) 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层  

4) 消息发送、响应机制(ApplicationEventPublisher)

5) AOP(拦截器)

两者装载bean的区别

BeanFactory:

BeanFactory在启动的时候不会去实例化Bean,中有从容器中拿Bean的时候才会去实例化;

ApplicationContext:

ApplicationContext在启动的时候就把所有的Bean全部实例化了。它还可以为Bean配置lazy-init=true来让Bean延迟实例化; 

8.AOP

 

9.spring循环依赖问题

循环依赖问题在Spring中主要有三种情况:

(1)通过构造方法进行依赖注入时产生的循环依赖问题。

(2)通过setter方法进行依赖注入且是在多例(原型)模式下产生的循环依赖问题。

(3)通过setter方法进行依赖注入且是在单例模式下产生的循环依赖问题。

在Spring中,只有第(3)种方式的循环依赖问题被解决了,其他两种方式在遇到循环依赖问题时都会产生异常。这是因为:

第一种构造方法注入的情况下,在new对象的时候就会堵塞住了,其实也就是”先有鸡还是先有蛋“的历史难题。

第二种setter方法(多例)的情况下,每一次getBean()时,都会产生一个新的Bean,如此反复下去就会有无穷无尽的Bean产生了,最终就会导致OOM问题的出现。

代码块
 
 
 
 
 
 
假设TestA、TestB、TestC三者循环依赖
具体步骤
1.spring容器创建testA 的bean对象,首先根据无参构造器创建bean,并暴露一个ObjectFactory用于返回一个提前暴露一个创建中的bean,并将testA标识放到当前创建bean池,然后进行setter注入testB
2.spring容器创建testB 的bean对象,首先根据无参构造器创建bean,并暴露一个ObjectFactory用于返回一个提前暴露一个创建中的bean,并将testB标识放到当前创建bean池,然后进行setter注入testC
3.spring容器创建testC 的bean对象,首先根据无参构造器创建bean,并暴露一个ObjectFactory用于返回一个提前暴露一个创建中的bean,并将testC标识放到当前创建bean池,然后进行setter注入testA。进行注入testA时,由于提前暴露了ObjectFactory工厂,从而使用它返回提前暴露一个创建中的bean
4.最后再依赖注入testB和testA,完成setter注入
 

10.spring设计模式

https://www.cnblogs.com/chinaifae/p/10393930.html

 

11.spring mvc

(1)用户发送请求至前端控制器DispatcherServlet;

(2)DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handler;

(3)处理器映射器根据请求url找到具体的处理器Handler,生成处理器对象及处理器拦截器(如果有则生成),一并返回给DispatcherServlet;

(4)DispatcherServlet 调用 HandlerAdapter处理器适配器,请求执行Handler;

(5)HandlerAdapter 经过适配调用 具体处理器进行处理业务逻辑;

(6)Handler执行完成返回ModelAndView;

(7)HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;

(8)DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析;

(9)ViewResolver解析后返回具体View;

(10)DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)

(11)DispatcherServlet响应用户。

前端控制器 DispatcherServlet:接收请求、响应结果,相当于转发器,有了DispatcherServlet 就减少了其它组件之间的耦合度。

处理器映射器 HandlerMapping:根据请求的URL来查找Handler

处理器适配器 HandlerAdapter:负责执行Handler

处理器 Handler:处理器,需要程序员开发

视图解析器 ViewResolver:进行视图的解析,根据视图逻辑名将ModelAndView解析成真正的视图(view)

视图View:View是一个接口, 它的实现类支持不同的视图类型,如jsp,freemarker,pdf等等

12.spring获取bean流程

1、扫描 ----> 创建BeanDefinition对象 ———>放到beanDefinitionMap中

2、验证 遍历beanDefinitionMap,验证类是否能被创建出来(是否是singleton 是否是抽象类,是否是懒加载,是否是FactoryBean接口的实现类 id属性是否合法 等等),将最终的Bean的id存到一个Set集合中(singleton类型的),这个Set集合的名字是SingletonsCurrentlyInCreation 当一个Bean的生命周期全部结束后,会将这个id移除掉,

3、得到Bean的class对象,根据注入模型,如果设置了构造模式就推断构造方法,判断要使用哪个构造方法进行创建对象,没有设置构造模式默认使用的就是无参的构造方法

4、得到构造器对象,使用反射实例化对象

5、合并BeanDefinition,主要是合并有父类的bean

6、提前暴露一个bean工厂对象---->为了解决循环依赖

7、填充属性,对属性的注入

8、执行部分aware接口,比如ApplicationContextAware接口,为其注入ApplicationContext工厂,等 并执行实现BeanPostProcessor接口中重新的postProcessBeforeInitialization()方法

9、执行剩下的aware接口,并执行Bean的初始化方法,即@PostConstruct标注的方法

10、执行接口版和自定义xml配置版的初始化方法(即实现了InitializingBean接口重写的方法afterPropertiesSet())

11、执行实现的BeanPostProcessor接口的postProcessAfterInitialization()方法,aop代理就是在此方法中完成的

12、将Bean放到单例池中(一级缓存)

13、获取工厂后调用getBean(“id”)调用的就是BeanFactory的doGetBean()方法

posted @ 2022-04-08 14:28  刘尊礼  阅读(52)  评论(0)    收藏  举报