1. Spring框架核心架构解析
Spring框架作为Java企业级开发的基石,其核心设计思想始终围绕着两个基本理念:控制反转(IoC)和面向切面编程(AOP)。这两个概念构成了Spring生态系统的DNA,理解它们对于掌握Spring技术栈至关重要。
1.1 IoC容器实现机制
Spring IoC容器的实现基于工厂模式与反射机制,其核心接口BeanFactory定义了最基本的容器功能。在实际开发中,我们更多使用其扩展接口ApplicationContext,它提供了更多企业级特性:
// 典型容器初始化方式 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); // 或者基于注解配置的方式 AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);容器启动时经历的关键阶段包括:
- 资源定位:根据配置路径加载XML或扫描注解
- Bean定义解析:将配置转换为BeanDefinition对象
- 依赖注入:解析并建立Bean之间的依赖关系
- 初始化回调:执行@PostConstruct等生命周期方法
重要提示:Spring 5.x版本后,官方推荐使用注解配置而非XML配置,但理解XML配置方式对于维护遗留系统仍然必要。
1.2 AOP实现原理
Spring AOP基于动态代理实现,根据目标类是否实现接口选择JDK动态代理或CGLIB:
- JDK动态代理:要求目标类至少实现一个接口,运行时生成接口的实现类
- CGLIB代理:通过继承目标类生成子类实现代理,不需要接口
代理对象的创建过程:
// 简化的代理创建逻辑 public Object createProxy(Class<?> targetClass) { if (targetClass.getInterfaces().length > 0) { return Proxy.newProxyInstance(/* JDK代理参数 */); } else { return Enhancer.create(/* CGLIB参数 */); } }AOP的核心概念包括:
- 切点(Pointcut):定义在哪些方法上应用通知
- 通知(Advice):定义在方法执行的什么时机插入逻辑
- 切面(Aspect):切点与通知的组合
2. 事务管理深度剖析
2.1 声明式事务实现原理
Spring事务管理的核心是TransactionInterceptor,它通过AOP将事务逻辑织入到业务方法中。事务的传播行为和隔离级别通过@Transactional注解配置:
@Transactional( propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, timeout = 30, rollbackFor = {SQLException.class} ) public void businessMethod() { // 业务逻辑 }事务传播行为的七种类型中,最常用的是:
- REQUIRED:默认值,当前有事务就加入,没有就新建
- REQUIRES_NEW:总是新建事务,挂起当前事务(如果存在)
- NESTED:在当前事务中嵌套子事务
2.2 事务同步机制
Spring通过TransactionSynchronizationManager实现资源同步,关键方法包括:
// 绑定资源到当前线程 TransactionSynchronizationManager.bindResource(key, value); // 注册同步回调 TransactionSynchronizationManager.registerSynchronization( new TransactionSynchronization() { @Override public void afterCompletion(int status) { // 事务完成后处理 } } );常见的事务失效场景及解决方案:
- 自调用问题:同一个类中方法调用不会触发代理
- 解决方案:通过AopContext.currentProxy()获取代理对象
- 异常捕获不当:捕获了异常但没有重新抛出
- 正确做法:在catch块中抛出RuntimeException
- 非public方法:Spring默认只代理public方法
- 解决方案:修改方法可见性或调整代理配置
3. MyBatis整合实战
3.1 整合配置详解
Spring与MyBatis整合的核心是SqlSessionFactoryBean,它负责创建MyBatis的SqlSessionFactory。典型配置如下:
@Bean public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) { SqlSessionFactoryBean factory = new SqlSessionFactoryBean(); factory.setDataSource(dataSource); factory.setTypeAliasesPackage("com.example.model"); factory.setMapperLocations( new PathMatchingResourcePatternResolver() .getResources("classpath:mappers/*.xml")); return factory; }整合过程中的关键点:
- Mapper扫描配置:使用@MapperScan或 mybatis:scan 自动注册Mapper接口
- 事务管理器配置:需要配置DataSourceTransactionManager
- 分页插件集成:如PageHelper的配置
3.2 动态SQL高级技巧
MyBatis的动态SQL能力是其核心优势之一,以下是几种高级用法:
条件构造:
<select id="findUsers" resultType="User"> SELECT * FROM users <where> <if test="name != null"> AND name = #{name} </if> <if test="age != null"> AND age = #{age} </if> </where> </select>批量操作:
<insert id="batchInsert"> INSERT INTO users (name, age) VALUES <foreach collection="list" item="user" separator=","> (#{user.name}, #{user.age}) </foreach> </insert>结果映射:
<resultMap id="userResultMap" type="User"> <id property="id" column="user_id"/> <result property="name" column="user_name"/> <collection property="roles" ofType="Role"> <id property="id" column="role_id"/> <result property="name" column="role_name"/> </collection> </resultMap>4. 性能优化与最佳实践
4.1 Spring性能调优
Bean作用域选择:
- 单例(singleton):默认值,适合无状态Bean
- 原型(prototype):每次请求创建新实例,适合有状态Bean
- 请求(request)、会话(session):Web环境中使用
延迟初始化:
@Configuration @Lazy public class AppConfig { // 配置类中的所有Bean将延迟初始化 }- 方法缓存:
@Cacheable(value = "users", key = "#id") public User getUserById(Long id) { // 数据库查询 }4.2 MyBatis优化策略
一级缓存管理:
- SqlSession级别的缓存,默认开启
- 在事务中重复查询相同数据会命中缓存
- 可通过localCacheScope配置(SESSION/STATEMENT)
二级缓存配置:
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>- 批量操作优化:
try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) { UserMapper mapper = session.getMapper(UserMapper.class); for (User user : userList) { mapper.insert(user); } session.commit(); }5. 常见问题排查指南
5.1 Spring典型问题
Bean循环依赖:
- 现象:启动时报BeanCurrentlyInCreationException
- 解决方案:
- 使用setter注入替代构造器注入
- 使用@Lazy延迟初始化
- 重构设计,消除循环依赖
事务不生效:
- 检查点:
- 方法是否为public
- 是否自调用
- 异常类型是否匹配rollbackFor
- 数据源是否配置了事务管理器
5.2 MyBatis集成问题
Mapper接口未注册:
- 检查点:
- @MapperScan基包路径是否正确
- Mapper.xml文件是否在classpath下
- XML中namespace是否与接口全限定名一致
类型处理器问题:
- 自定义类型处理器示例:
@MappedTypes(PhoneNumber.class) @MappedJdbcTypes(JdbcType.VARCHAR) public class PhoneTypeHandler extends BaseTypeHandler<PhoneNumber> { // 实现类型转换逻辑 }动态SQL错误:
- 常见错误:
- 条件判断中使用==代替eq
- 集合遍历时item与collection混淆
- 转义字符处理不当(如<需要写成<)