一、SpringMVC
MVC 是模型(Model)、视图(View)、控制器(Controller)的简写,其核心思想是通过将业务逻辑、数据、显示分离来组织代码。
SpringMVC的核心组件:
DispatcherServlet
:核心的中央处理器,负责接收请求、分发,并给予客户端响应。HandlerMapping
:处理器映射器,根据 uri 去匹配查找能处理的Handler
,并会将请求涉及到的拦截器和Handler
一起封装。HandlerAdapter
:处理器适配器,根据HandlerMapping
找到的Handler
,适配执行对应的Handler
;Handler
:请求处理器,处理实际请求的处理器。ViewResolver
:视图解析器,根据Handler
返回的逻辑视图 / 视图,解析并渲染真正的视图,并传递给DispatcherServlet
响应客户端
SpringMVC的工作原理
流程说明:
- 客户端(浏览器)发送请求,
DispatcherServlet
拦截请求。 DispatcherServlet
根据请求信息调用HandlerMapping
。HandlerMapping
根据 uri 去匹配查找能处理的Handler
(也就是Controller
控制器) ,并会将请求涉及到的拦截器和Handler
一起封装。DispatcherServlet
调用HandlerAdapter
适配器执行Handler
。Handler
完成对用户请求的处理后,会返回一个ModelAndView
对象给DispatcherServlet
,ModelAndView
顾名思义,包含了数据模型以及相应的视图的信息。Model
是返回的数据对象,View
是个逻辑上的View
。ViewResolver
会根据逻辑View
查找实际的View
。DispaterServlet
把返回的Model
传给View
(视图渲染)。- 把
View
返回给请求者(浏览器)
二、Spring IOC
IoC(Inversion of Control:控制反转) 是一种设计思想,而不是一个具体的技术实现。IoC 的思想就是将原本在程序中手动创建对象的控制权,交由 Spring 框架来管理。不过, IoC 并非 Spring 特有,在其他语言中也有应用。
将对象之间的相互依赖关系交给 IoC 容器来管理,并由 IoC 容器完成对象的注入。这样可以很大程度上简化应用的开发,把应用从复杂的依赖关系中解放出来。 IoC 容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不用考虑对象是如何被创建出来的。
Spring的IOC容器使用了依赖注入(Dependency Injection,DI)的方式来实现对象之间的解耦。依赖注入是一种将依赖对象注入到需要依赖对象的组件中的方法。在Spring中,依赖注入主要通过以下方式实现:
-
构造函数注入(Constructor Injection):通过构造函数注入,容器会调用Bean的构造函数来创建Bean实例,并将所需的依赖对象作为参数传递给构造函数。
-
Setter方法注入(Setter Injection):通过Setter方法注入,容器会调用Bean的Setter方法来注入依赖对象。
-
字段注入(Field Injection):通过字段注入,容器会直接将依赖对象注入到Bean的字段中。
通过依赖注入,组件可以将依赖对象与组件本身解耦。这样,在组件的依赖关系发生变化时,只需要修改IOC容器的配置文件,而无需修改应用程序代码。
总之,Spring的IOC容器使用了依赖注入的方式来实现对象之间的解耦。通过IOC容器,应用程序中的组件可以获取所需的依赖对象,从而实现组件之间的解耦。
将一个类声明为 Bean 的注解有哪些?
@Component
:通用的注解,可标注任意类为Spring
组件。如果一个 Bean 不知道属于哪个层,可以使用@Component
注解标注。@Repository
: 对应持久层即 Dao 层,主要用于数据库相关操作。@Service
: 对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao 层。@Controller
: 对应 Spring MVC 控制层,主要用于接受用户请求并调用Service
层返回数据给前端页面。
Spring Bean的生命周期
1.实例化:当 Spring 容器接收到配置文件或注解配置后,会通过反射机制实例化一个 Bean。
2.设置属性:在实例化 Bean 后,Spring 容器会使用反射机制调用 Bean 的 setter 方法或直接为属性赋值来设置 Bean 的属性。
3.调用 Bean 的初始化方法:如果 Bean 实现了 InitializingBean 接口,Spring 容器会在设置 Bean 的属性之后调用其 afterPropertiesSet() 方法;如果在配置文件中配置了 init-method 属性,则会调用指定名称的方法。
4.引用注入:Spring 容器会把该 Bean 注入到其他 Bean 中。
5.使用 Bean:Bean 正常运行时处于使用状态。
6.调用 Bean 的销毁方法:如果 Bean 实现了 DisposableBean 接口,Spring 容器在销毁 Bean 之前会调用接口的 destroy() 方法;如果在配置文件中配置了 destroy-method 属性,则会调用指定名称的方法。
三、Spring AOP
AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。
Spring AOP 就是基于动态代理的,如果要代理的对象,实现了某个接口,那么 Spring AOP 会使用 JDK Proxy,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候 Spring AOP 会使用 Cglib 生成一个被代理对象的子类来作为代理。
五种通知类型
- Before(前置通知):目标对象的方法调用之前触发
- After (后置通知):目标对象的方法调用之后触发
- AfterReturning(返回通知):目标对象的方法调用完成,在返回结果值之后触发
- AfterThrowing(异常通知):目标对象的方法运行中抛出 / 触发异常后触发。AfterReturning 和 AfterThrowing 两者互斥。如果方法调用成功无异常,则会有返回值;如果方法抛出了异常,则不会有返回值。
- Around (环绕通知):编程式控制目标对象的方法调用。环绕通知是所有通知类型中可操作范围最大的一种,因为它可以直接拿到目标对象,以及要执行的方法,所以环绕通知可以任意的在目标对象的方法调用前后搞事,甚至不调用目标对象的方法
SpringAOP的应用场景
Aspect框架提供的AOP可以应用于各种场景,以下是一些常见的实际应用:
1、日志记录:例如使用AOP记录用户登录时间的日志。
通过AOP实现对系统的日志记录,可以在方法执行前后记录方法名、参数、执行时间等信息,便于系统运维和问题排查。
2、安全控制:例如在用户登录后,将用户的权限查询后放在springsecurityContext中,写一个注解,用于鉴权,在需要鉴权的方法上使用该注解,写一个切面,里面实现对该注解的鉴权的定义。
通过AOP实现对系统的安全控制,可以在方法执行前检查用户的权限、身份认证等信息,以确保系统的安全性。
3、性能监控
通过AOP实现对系统的性能监控,可以在方法执行前后记录方法的执行时间、耗时等信息,以便于优化系统的性能。
4、事务管理
通过AOP实现对系统的事务管理,可以在方法执行前开启事务,在方法执行后提交或回滚事务,以确保系统的数据完整性和一致性。
5、缓存管理
通过AOP实现对系统的缓存管理,可以在方法执行前查询缓存,如果缓存存在,则直接返回缓存数据;如果缓存不存在,则执行方法并将结果存入缓存,以加速系统的访问速度。
总的来说,AOP在各个领域都有广泛的应用,可以大大简化系统开发和维护的工作量,提高系统的可维护性、可扩展性和可重用性。
四、SpringBoot自动装配原理
在springboot启动的时候,核心部分就是注解定义(**@SpringBootApplication**)和类定义(**SpringApplication.run**)
在springboot启动的时候,run方法给我们做了几件事情:
1. 把当前启动类.class参数设置到SpringApplication中,这个参数sources可以是任何类型的参数
2. 获取应用类型,判断是否是web程序,并设置到webEnvironment的boolean属性中
3. 创建并初始化ApplectionInitializer(初始化器),设置到initializers属性中
4. 创建并初始化ApplicationListener(初监听器),设置到listeners属性中
5. 初始化主类mainApplectionClass,定位main方法。
@SpringBootApplication分析,它下面还有三个注解:
1. @SpringBootConfiguration:这个注解下面还有一个注解@Configuration,代表它其实就是一个配置类,相当于传统的 Spring XML 配置文件。
2. @EnableAutoConfiguration:开启 Spring Boot 的自动配置功能,Spring Boot 会根据 classpath 下的 jar 包自动配置 Spring 框架所需的组件和 Bean。
3. @ComponentScan:自动扫描指定包及其子包下的所有组件和 Bean。可以通过指定 basePackages、basePackageClasses 或者 value 来指定扫描的包。
在 Spring Boot 应用中,通过 @EnableAutoConfiguration 注解来开启自动配置功能,它会扫描 classpath 下的 META-INF/spring.factories 文件,加载所有的自动配置类,然后将它们都注册到 Spring 容器中。
五、Spring事务传播机制
Spring 事务的传播机制用于控制在一个事务方法中调用其他事务方法时,这些方法如何共享事务。Spring 提供了多种事务传播行为,可以通过 @Transactional 注解或 XML 配置文件来设置。
下面介绍几种常见的事务传播行为:
1. PROPAGATION_REQUIRED(默认值):如果当前方法正在一个事务中运行,则使用该事务;否则,开启一个新的事务。
2. PROPAGATION_SUPPORTS:如果当前方法正在一个事务中运行,则使用该事务;否则,不使用事务。
3. PROPAGATION_MANDATORY:如果当前方法正在一个事务中运行,则使用该事务;否则,抛出异常。
4. PROPAGATION_REQUIRES_NEW:无论当前方法是否正在一个事务中运行,都开启一个新的事务。
5. PROPAGATION_NOT_SUPPORTED:如果当前方法正在一个事务中运行,则挂起该事务;否则,不使用事务。
6. PROPAGATION_NEVER:如果当前方法正在一个事务中运行,则抛出异常;否则,不使用事务。
7. PROPAGATION_NESTED:如果当前方法正在一个事务中运行,则在该事务中创建一个嵌套事务;否则,开启一个新的事务。嵌套事务是一个独立的事务,有自己的提交和回滚操作,但是如果外部事务回滚,嵌套事务也会被回滚。