解析 Spring Framework、Spring Boot 和 MyBatis 的核心机制
Spring 生态是 Java 后端开发的“基础设施”从底层的 Bean 管理到上层的微服务架构形成了一套完整的技术栈。理解其核心原理不仅能让你在面试中对答如流更能帮助你在实际开发中解决复杂的架构问题。以下结合具体业务场景深度解析 Spring Framework、Spring Boot 和 MyBatis 的核心机制。一、Spring Framework生态的“地基”Spring Framework 的核心在于IoC控制反转和AOP面向切面编程它们共同支撑起了企业级应用开发的复杂性。1. Bean 生命周期IOC 容器的“心脏”Spring 容器管理 Bean 的全过程可以概括为实例化 - 属性赋值 - 初始化 - 销毁。实例化 (Instantiation)容器通过反射调用构造器在内存中创建一个空的 Bean 对象。属性赋值 (Population)容器将依赖的 Bean 或配置值注入到当前 Bean 中如Autowired注解的字段。初始化 (Initialization)这是生命周期中最复杂、扩展性最强的阶段。Aware 接口回调如果 Bean 实现了BeanNameAware、BeanFactoryAware等接口容器会调用相应方法让 Bean 能够感知到自身在容器中的信息如 Bean 名称、容器本身。BeanPostProcessor(BPP) 前置处理这是 Spring 框架提供的“魔法”入口。在 Bean 初始化之前所有注册的BeanPostProcessor的postProcessBeforeInitialization方法会被调用。Spring AOP 的代理对象就是在这里生成的。初始化方法执行依次执行PostConstruct注解的方法、InitializingBean接口的afterPropertiesSet()方法以及 XML 中配置的init-method。BeanPostProcessor(BPP) 后置处理所有 BPP 的postProcessAfterInitialization方法被调用可以对已初始化的 Bean 进行最终包装或替换。使用Bean 准备就绪被放入一级缓存 (singletonObjects)供其他组件使用。销毁 (Destruction)容器关闭时会执行PreDestroy、DisposableBean接口的destroy()方法等释放资源。关键考点循环依赖Spring 通过三级缓存巧妙地解决了单例 Bean 的循环依赖问题如 A 依赖 BB 又依赖 A。一级缓存 (singletonObjects)存放完全初始化好的成品 Bean。二级缓存 (earlySingletonObjects)存放提前暴露的、未完成属性注入和初始化的“半成品”Bean。三级缓存 (singletonFactories)存放 Bean 工厂 (ObjectFactory)用于在需要时生成 Bean 的早期引用可能是原始对象也可能是 AOP 代理对象。场景流程 (A - B - A)创建 A实例化后将其工厂放入三级缓存。A 注入属性 B发现 B 不存在转而去创建 B。创建 B实例化后将其工厂放入三级缓存。B 注入属性 A从三级缓存中获取 A 的工厂调用getObject()得到 A 的早期引用放入二级缓存并从三级缓存移除工厂注入给 B。B 完成初始化放入一级缓存。A 获得 B完成自身初始化放入一级缓存。2. AOP (面向切面编程)解耦“横切关注点”AOP 的核心思想是将日志、事务、权限校验等通用逻辑横切关注点从业务逻辑中剥离出来实现模块化。实现原理动态代理。JDK 动态代理目标类必须实现接口。代理类实现相同的接口在方法调用前后织入切面逻辑。CGLIB 代理目标类没有实现接口。通过生成目标类的子类重写其方法来实现代理。核心术语切面 (Aspect)切点 通知的组合如Aspect注解的类。切点 (Pointcut)通过表达式定义“在哪里”切入如“所有 Service 层的方法”。通知 (Advice)在切点执行的代码如Before、After、Around。3. 声明式事务Transactional的“双刃剑”Transactional是 Spring 最常用的注解之一其底层原理就是AOP 数据库事务。原理Spring 在启动时会为带有Transactional注解的 Bean 创建一个事务代理对象。当调用该代理对象的方法时代理会先开启一个数据库事务然后执行目标方法最后根据方法执行情况提交或回滚事务。失效场景自调用 (Self-invocation)在同一个类中一个非事务方法 A 调用事务方法 B。因为 A 调用的是this.B()绕过了代理对象导致事务切面失效。方法非 publicTransactional只能用于 public 方法否则代理无法正确拦截。异常被吞方法内部用try-catch捕获了异常事务管理器感知不到异常自然不会回滚。4. Spring MVCWeb 层的“标准化引擎”Spring MVC 的核心是DispatcherServlet它作为前端控制器统一接收所有 HTTP 请求并分发给相应的处理器。请求处理流程客户端发送请求到DispatcherServlet。DispatcherServlet查询HandlerMapping找到处理该请求的Controller。DispatcherServlet将请求交给HandlerAdapter去执行Controller的方法。Controller执行完毕返回ModelAndView。HandlerAdapter将结果返回给DispatcherServlet。DispatcherServlet将ModelAndView交给ViewResolver解析成具体的视图。视图渲染响应给客户端。二、Spring BootSpring 的“加速器”Spring Boot 的核心使命是简化配置实现“开箱即用”。1. 自动装配 (Auto-Configuration)约定优于配置这是 Spring Boot 最核心的特性它根据你添加的依赖Starter自动配置 Spring 应用。核心注解EnableAutoConfiguration。实现原理Spring Boot 启动时会扫描所有 Jar 包下的META-INF/spring.factories(或新版本org.springframework.boot.autoconfigure.AutoConfiguration.imports) 文件。这些文件中定义了海量的自动配置类如DataSourceAutoConfiguration,RedisAutoConfiguration。这些配置类通过Conditional系列注解如ConditionalOnClass,ConditionalOnMissingBean来判断当前环境。例如当 classpath 下存在HikariCP类时DataSourceAutoConfiguration才会生效自动创建一个HikariDataSource的 Bean。2. 启动流程从main到 RunningSpring Boot 的启动过程可以概括为四个关键步骤环境准备加载并准备Environment包括命令行参数、环境变量、application.yml等配置文件。创建 Context根据应用类型Servlet/Reactive创建合适的ApplicationContext。刷新 Context这是最核心的一步。它会执行自动配置、扫描并注册 Bean、实例化所有非懒加载的单例 Bean。运行 Runner调用所有CommandLineRunner和ApplicationRunnerBean 的run方法执行启动后的逻辑。三、MyBatis灵活的 SQL 映射框架MyBatis 的核心是将 SQL 与 Java 代码解耦并通过插件机制提供强大的扩展能力。1. 核心执行流程一次 SQL 查询的执行涉及四大核心组件的协作SqlSession作为顶层 API是应用与 MyBatis 交互的接口。ExecutorSQL 执行的真正调度者负责缓存管理、事务控制等。StatementHandler负责创建Statement对象如PreparedStatement并设置 SQL 参数。ParameterHandler/ResultSetHandler分别负责将 Java 对象映射为 SQL 参数以及将 SQL 查询结果映射为 Java 对象。2. 插件 (Plugin)基于责任链的拦截器MyBatis 的插件机制允许我们在不修改核心代码的情况下增强其功能如实现分页、性能监控、数据加密等。实现原理责任链模式 动态代理。拦截点Executor,StatementHandler,ParameterHandler,ResultSetHandler。核心接口Interceptorintercept(Invocation invocation)核心拦截逻辑。可以在这里修改 SQL、参数或结果集。plugin(Object target)MyBatis 使用该方法包装目标对象生成代理。setProperties(Properties p)接收配置文件中定义的属性。业务场景SQL 性能监控我们可以编写一个Interceptor拦截StatementHandler.prepare()方法。在intercept方法中记录执行前的系统时间。调用invocation.proceed()执行原始 SQL。记录执行后的时间计算出 SQL 执行耗时。如果耗时超过阈值如 1 秒则打印警告日志帮助定位慢查询。通过这种方式我们可以轻松地为整个应用添加统一的 SQL 审计功能而无需在每个 DAO 方法中手动添加计时逻辑。