Spring
核心特性
- IOC容器:控制反转;AOP面向切面编程;事务管理;MVC框架
- 依赖注入:把对象创建和依赖的关系交给Spring,常见的有构造方法注入,setter注入,还有字段通过这个@Autowired注入
Spring IOC
- 传统开发过程中,我们需要通过new关键字来创建对象。应用程序不在控制对象的创建,而是被动的接受容器注入的对象
- 主要优点:使用者不必关心bean创建的一个细节,不用创建多个相同的bean浪费资源,然后大大降低了对象之间的一个耦合度
Spring AOP
- 面向切面编程,主要是为了减少系统重复的代码,降低模块之间的一个耦合度,对代码进行一个额外的处理,增加额外的功能和逻辑,比如拦截进行参数的校验,缓存,日志打印等
- 几个概念:切面(@Aspect),连接点(@PointCut),通知,AOP代理,目标对象,@Before,@After,@Around,@Advice通知类型
- Spring AOP默认使用的是这个JDK动态代理:这个动态代理他要求必须要实现一个或者多个接口,核心是InvacationHandler和Proxy类,需要在这个实现InvactionHandler的类里面重写这个invoke,也就是我们要增加的这个额外的逻辑
- 如果不实现接口就使用这个CGLIB动态代理,这个主要的核心是MethodIntercepter核心接口,要去重写这个intercept()方法,通过enhancer生成代理对象,然后这个代理类是去继承了这个目标对象当做他的父类,通过这个代理对象去调用这个方法。我了解到的目前这个springboot在2.x以上就默认有限使用这个cglib动态代理,因为JDK动态代理需要实现接口比较麻烦。
- 静态代理和动态代理的区别:静态代理是在编译期生成,需要手动写一个代理类,一个代理类只能代理一个目标,代码的耦合度很高。动态代理是在运行期的时候运用反射机制反射,生成代理类,一个代理类能代理任意目标类
- 比如在项目中用户登录登出的时间信息,登录状态,用户ID,包括博客的发布时间,发布者等等日志信息都可以使用这个AOP进行打印或者记录
反射机制
- 程序在运行的时候能够获得自身的信息,只要给定类名,就可以获得这个类所有的成员变量以及相关的方法,在运行时刻能够调用一个对象的方法,并且可以构造对象
- 但是他也有缺点,反射他破坏了类的封装性,并且可读性和可维护性很低,而且还很慢,主要是他涉及到动态解析,有一些JVM的优化比如JIT优化不能实现,还有使用反射的时候参数需要包装成Object,但是真正执行方法的时候他又要拆包成一个真正的类型,这些过程都是很耗时的
- 使用的场景,SpringIOC/AOP,ORM框架比如说mybatis,java字段和数据库字段进行一个映射,动态代理
Spring三级缓存(Map存储)
- 循环依赖:A对象依赖于B对象的创建,B对象依赖A对象的创建
- 一级缓存:存储的是已经完全初始化好的bean,以及准备好可以使用了。键是bean的名称,value是键的一个实例,存在这个DefaultSingletonRegistry中的singletonObjects属性中
- 二级缓存:存储的是早期的bean的引用,就是已经实例化但是还没有进行一些属性的注入操作,在earlySingletonObjects属性中
- 三级缓存:存储bean工厂对象ObjectFactory,可以生产早期的bean引用。当一个bean正在创建,如果被其他的bean依赖,那么这个正在创建的bean就会通过这个ObjectFactory创建一个早期引用来解决这个循环依赖问题。A,B都卡主的时候,通过这个三级缓存会创建一个半成品的BeanA,然后放到这个二级缓存中,删掉三级缓存中的BeanA,然后用这个早期引用创建B,放入到一级缓存,再通过一级缓存中的beanB创建beanA
Spring常用注解
-
@Autowired注解,@Component,@Configuration,@Bean,@Service,@Controller(默认返回视图,然后进行页面的跳转),@RestController返回值序列化成这个JSON/XML,中间通过Jackson进行转换.
-
@RequestMapping,@GetMapping/@PostMapping
-
@RequestParam(URL拼接的一个参数),@PathVariable(是这个路径中的变量),@RequestBody(获取请求体,比如传进来一个User对象要使用这个接收)
-
@cacheable这个Spring的缓存管理,需要结合这个@EnableCaching开启
-
@Transactional核心注解:核心属性有:事务传播行为,事务隔离级别,指定触发回滚的异常,事务超时时间,是否只读
-
事务隔离级别:默认数据库的隔离级别,读未提交,读已提交,可重复读,串行化
-
事务传播行为(7种):
- Required:当前有事务就加入该事物,没有创建
- Required New:不管有没有都创建新事物
- Supports:如果当前有就加入,没有以非事务方式执行
- Not Supports:以非事务方式执行,如果当前有事务就挂起
- Mandatory:必须在现有事务中执行,否则抛异常
- Never:必须以非事务方式执行,否则抛异常
- Nested:如果当前有事务,嵌套在该事务内执行,如果没有就创建
-
事务失效:
- 方法非public修饰,Spring事务基于AOP动态代理,仅拦截public方法
- 同类内部调用:如a()调用同类@Transactional的b()方法,跳过代理对象,直接调用原方法
@Service public class UserService { public void a() { this.b(); // 内部调用,事务失效 } @Transactional public void b() { /* 事务逻辑 */ } }- 事务方法内的异常被捕捉没有抛出,Spring感知不到就不会回滚
- 错误的异常类型,@Transactional默认支持回滚RunTimeExecption和Error,其他的异常需要手动添加,要不然就不会回滚
- 方法被final/static修饰,倒是无法被动态代理重写,AOP增强失败,事务无法生效
- 自己New的对象没有被IOC容器管理,注解无法被解析
-
数据库和并发编程的原子性是不一样的,在数据库中所有操作要么成功要么回滚,在并发编程中原子性是指操作不可被拆分中断
Springboot的run方法后启动流程
- 初始化 SpringApplication:推断应用类型(Web / 非 Web),加载初始化器(ApplicationContextInitializer)、监听器(ApplicationListener);
- 准备环境:创建 Environment,加载配置文件(yml/properties)、环境变量、命令行参数,激活指定 Profiles;
- 创建 IOC 容器:根据应用类型创建对应 ApplicationContext(如 Web 应用创建 AnnotationConfigServletWebServerApplicationContext);
- 刷新容器(核心):
- 加载并解析 Bean 定义(扫描 @Controller/@Service 等注解);
- 执行 BeanFactoryPostProcessor(修改 Bean 定义)、注册 BeanPostProcessor(Bean 增强);
- 实例化并初始化非懒加载单例 Bean(依赖注入、@PostConstruct 执行);
- 启动内嵌容器(Tomcat/Jetty),绑定端口;
- 启动收尾:执行 ApplicationRunner/CommandLineRunner(启动后自定义逻辑),发布启动完成事件,应用对外提供服务。
拦截器和过滤器的区别
- 过滤器属于 Servlet 规范,拦截所有请求(包括静态资源),执行时机更早,仅能操作 Servlet 上下文;
- 拦截器是 Spring 框架自带的,仅拦截 Controller 请求,可访问 Spring IOC 容器、按方法 / 注解精细拦截,灵活性更高;
- 执行顺序:Filter 先执行,再到 Interceptor(preHandle),Controller 执行后走 Interceptor 后续方法,最后回到 Filter。
Bean对象的生命周期
- 实例化,通过反射new出来一个空对象,属性还没有赋值
- 属性赋值:
- 初始化前可以进行一些自定义的前置处理
- 初始化时:使用自定义的初始化逻辑:注解,接口,xml
- 初始化后:也有扩展点,像Spring AOP就是在这一步生成的
- 使用
- 销毁
MVC流程框架
- DispatcherServlet会调用HandlerMapping根据URL映射找到对应的方法
- 调用HandlerAdaptor,解析参数比如@PathVariable中的{id},调用对应方法执行业务逻辑,封装返回结果
- 异常处理使用HandlerExceptionResolver
- ViewResolver视图解析
- M(model层处理业务逻辑+数据),V(view视图),Controller(控制器),Filter是在servlet容器层之外进行过滤,在DispatcherServlet之前

SpringCloud组件
- 注册中心,负载均衡,日志集中管理中心,配置中心,服务保护
springBoot的自动装配
- 他可以根据项目中引入的依赖,自动完成Spring框架所需要的核心配置,不用手动写大量的xml和java配置。主要是这个@SpringBootApplication注解,检测到相关的依赖就自动配置好相关的配置,像是控制器,视图解析器,静态资源等等

浙公网安备 33010602011771号