Spring

Spring

1.IOC

控制反转,传统开发中,通过new来创建对象,而IOC是将对象的创建,初始化,销毁交给了Spring容器。

IOC容器利用反射机制动态地加载类,创建对象实例以及调用对象方法。采用工厂模式来管理对象的生命周期,核心概念是依赖注入,由容器来管理类之间的依赖关系,包括构造函数注入,方法注入,字段注入。

2.AOP

面向切面编程,将与业务无关,却为业务模块所共同调用的逻辑封装起来(例如日志),以减少系统的重复代码,降低模块间的耦合度。

Spring AOP 是基于动态代理实现的,如果要代理的对象,实现了某个接口,那么 使用 JDK Proxy,去创建代理对象,而对于没有实现接口的对象,会使用 Cglib 生成一个被代理对象的子类来作为代理。在BeanPostProcessor中,把代理对象返回。

事务也是基于AOP实现的,在方法执行之前开启事务,执行之后提交事务

AOP里的概念:

3.循环依赖如何解决

三级缓存用来解决循环依赖问题:A类中有B属性,B类中有A属性

一级缓存:单例对象池,存储成品Bean,即实例化和初始化都完成的Bean

二级缓存:早期单例对象池,缓存半成品对象,且当前对象已经被其他对象引用了

三级缓存:单例工厂,通过工厂创建Bean

UserService和UserDao循环依赖的过程结合上述三级缓存描述一下

  • UserService 实例化对象,但尚未初始化,将UserService存储到三级缓存;
  • UserService 属性注入,需要UserDao,从缓存中获取,没有UserDao;
  • UserDao实例化对象,但尚未初始化,将UserDao存储到到三级缓存;
  • UserDao属性注入,需要UserService,从三级缓存获取UserService,UserService从三级缓存移入二级缓存;
  • UserDao执行其他生命周期过程,最终成为一个完成Bean,存储到一级缓存,删除二三级缓存;
  • UserService 注入UserDao;
  • UserService执行其他生命周期过程,最终成为一个完成Bean,存储到一级缓存,删除二三级缓存。

三级缓存它不是直接缓存对象,而是缓存一个能生产对象的工厂。当发生循环依赖时,调用这个工厂的 getObject() 方法,这时 Spring 会判断:如果这个 Bean 最终需要代理,就提前生成代理对象并放入二级缓存;如果不需要代理,就返回原始对象。这样一来,B 注入的 A 就是最终形态(可能是代理对象),后续 A 初始化完成后也不会再创建新代理,保证了对象全局唯一。

4.Bean的生命周期

实例化阶段:会将xml配置的的信息封装成一个BeanDefinition 对象,所有的BeanDefinition存储到一个名为beanDefinitionMap 的Map集合中去,Spring框架在对该Map进行遍历,使用反射创建 Bean实例对象。在BeanDefinitionMap填充完毕 ,Bean实例化之前执行Bean工厂后处理器,用于对BeanDefinition注册和修改。

初始化阶段:填充Bean实例属性,Aware接口属性注入,Bean后处理器,InitializingBean接口的初始化方法回调,自定义初始化方法init回调

完成阶段:经过初始化阶段,Bean就成为了一个完整的Spring Bean,被存储到单例池singletonObjects中去了,即完成了Spring Bean的整个生命周期。

5.Spring的常用注解

@Atuowired:自动装配

@Component:标记一个类作为Spring的Bean @Service @Controller @Repository

@Configuration:配置类 @Bean:标记方法作为Bean工厂方法

6.Spring事务什么情况下会失效?

  • 被代理方法不是public
  • 方法被final修饰(或者是static)
  • this调用 -- 手动生成一个代理对象去调用
  • 对象未被Spring管理
  • 不同数据源/数据库连接
  • 自己捕获异常
  • 抛出非运行时异常(只捕获运行时异常:RuntimeException(运行时异常)和Error(错误))

7.Bean的作用域有哪些?

singleton:单例,默认值,Spring容器创建的时候,就会进行Bean的实例化,并存储到容器内部的单例池中,每次getBean时都是从单例池中获取相同的Bean实例;

prototype:原型,Spring容器初始化时不会创建Bean实例,当调用getBean时才会实例化Bean,每次getBean都会创建一个新的Bean实例。生成的Bean不会存在单例池中。容器不管理销毁

SpringMVC

1.介绍一下SpringMVC

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面。

流程步骤:

  • 用户通过View 页面向服务端提出请求;
  • 服务端 Controller 控制器接收到请求后对请求进行解析,找到相应的Model,对用户请求进行处理Model 处理;
  • 将处理结果再交给 Controller;
  • 根据处理结果找到要作为向客户端发回的响应View 页面,页面经渲染后发送给客户端

2.SpringMVC的处理流程

Spring MVC的工作流程如下:

  1. 用户发送请求至前端控制器DispatcherServlet

  2. DispatcherServlet收到请求调用处理器映射器HandlerMapping。

  3. 处理器映射器根据请求url找到具体的处理器(Handler/Controller),生成处理器执行链HandlerExecutionChain(包括处理器对象和处理器拦截器)(多个拦截器方法的执行顺序)一并返回给DispatcherServlet。

  4. DispatcherServlet根据处理器Handler获取处理器适配器HandlerAdapter执行HandlerAdapter处理一系列的操作,如:参数封装,数据格式转换,数据验证等操作

  5. 执行处理器Handler(Controller,也叫页面控制器)。

  6. Handler执行完成返回ModelAndView

  7. HandlerAdapter将Handler执行结果ModelAndView返回到DispatcherServlet

  8. DispatcherServlet将ModelAndView传给ViewReslover视图解析器

  9. ViewReslover解析后返回具体View

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

  11. DispatcherServlet响应用户

3.过滤器和拦截器有什么区别?

  • 所属规范:过滤器是 Java Servlet 规范的一部分,而拦截器是 Spring 框架提供的机制。
  • 执行顺序:过滤器在请求进入 Servlet 容器后,在到达目标 Servlet 或控制器之前执行;拦截器在请求到达控制器之后,在控制器方法执行前后执行。
  • 使用范围:过滤器可以对所有类型的请求进行过滤,包括静态资源请求;拦截器只能对 Spring MVC 控制器的请求进行拦截。

SpringBoot

1.自动装配原理

当Spring容器启动后,一些配置类、bean对象就自动存入到了IOC容器中,不需要我们手动去声明。

  1. Spring Boot启动时加载@SpringBootApplication注解

  2. 该注解引入@EnableAutoConfiguration,进而触发自动配置机制

  3. 引入@Import(AutoConfigurationImportSelector.class),AutoConfigurationImportSelector类中读取META-INF/spring.factories中的自动配置类

  4. 过滤并排序这些自动配置类

  5. 根据条件注解判断哪些配置类应该生效

  6. 生效的配置类向容器中添加所需的Bean

2.起步依赖

igurationImportSelector类中读取META-INF/spring.factories中的自动配置类

  1. 过滤并排序这些自动配置类

  2. 根据条件注解判断哪些配置类应该生效

  3. 生效的配置类向容器中添加所需的Bean

2.起步依赖

原理是基于Maven的依赖传递。提供了快速的项目启动器,通过引入不同的 Starter,可以快速集成常用的框架和库(如数据库、消息队列、Web 开发等),极大地提高了开发效率。

相关推荐
进阶的小名2 小时前
[超轻量级延时队列(MQ)] Redis 不只是缓存:我用 Redis Stream 实现了一个延时MQ(自定义注解方式)
java·数据库·spring boot·redis·缓存·消息队列·个人开发
短剑重铸之日2 小时前
《7天学会Redis》Day 6 - 内存&性能调优
java·数据库·redis·缓存·7天学会redis
石头wang2 小时前
jmeter java.lang.OutOfMemoryError: Java heap space 修改内存大小,指定自己的JDK
java·开发语言·jmeter
AlexDeng2 小时前
EF Core 开发实践:Left Join 查询的多种实现方式
后端
yaoxin5211233 小时前
292. Java Stream API - 使用构建器模式创建 Stream
java·开发语言
马卡巴卡3 小时前
用Spring的ApplicationEventPublisher进行事件发布和监听
后端
阮松云3 小时前
code-server 配置maven
java·linux·maven
y***n6143 小时前
springboot项目架构
spring boot·后端·架构
木木木一3 小时前
Rust学习记录--C11 编写自动化测试
java·学习·rust