Spring框架核心架构与MyBatis整合实战
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动态代理或CGLIBJDK动态代理要求目标类至少实现一个接口运行时生成接口的实现类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 idfindUsers resultTypeUser SELECT * FROM users where if testname ! null AND name #{name} /if if testage ! null AND age #{age} /if /where /select批量操作insert idbatchInsert INSERT INTO users (name, age) VALUES foreach collectionlist itemuser separator, (#{user.name}, #{user.age}) /foreach /insert结果映射resultMap iduserResultMap typeUser id propertyid columnuser_id/ result propertyname columnuser_name/ collection propertyroles ofTypeRole id propertyid columnrole_id/ result propertyname columnrole_name/ /collection /resultMap4. 性能优化与最佳实践4.1 Spring性能调优Bean作用域选择单例singleton默认值适合无状态Bean原型prototype每次请求创建新实例适合有状态Bean请求request、会话sessionWeb环境中使用延迟初始化Configuration Lazy public class AppConfig { // 配置类中的所有Bean将延迟初始化 }方法缓存Cacheable(value users, key #id) public User getUserById(Long id) { // 数据库查询 }4.2 MyBatis优化策略一级缓存管理SqlSession级别的缓存默认开启在事务中重复查询相同数据会命中缓存可通过localCacheScope配置SESSION/STATEMENT二级缓存配置cache evictionLRU flushInterval60000 size512 readOnlytrue/批量操作优化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 BaseTypeHandlerPhoneNumber { // 实现类型转换逻辑 }动态SQL错误常见错误条件判断中使用代替eq集合遍历时item与collection混淆转义字符处理不当如需要写成