当前位置: 首页 > news >正文

Spring 框架核心技术详解:AOP、JDBC 模板与事务管理

在 Java 企业级开发中,Spring 框架凭借其强大的解耦能力和丰富的功能模块,成为开发者的首选工具。其中,AOP(面向切面编程)、JDBC 模板与事务管理是 Spring 生态的核心支柱,它们分别解决了代码重复、数据库操作繁琐、数据一致性保障三大痛点。本文将结合实战案例,从概念到落地,带大家系统掌握这些关键技术。

一、AOP:让通用逻辑与业务代码 “解耦”

1. 为什么需要 AOP?

在传统 OOP 开发中,日志记录、事务控制、权限校验等通用功能,会嵌入到各个业务方法中,导致代码冗余、耦合度高。例如转账业务中,“开启事务”“提交 / 回滚事务” 的逻辑,若直接写在pay()方法里,后续修改时需逐个调整,维护成本极高。

AOP 通过横向抽取机制,将通用功能(称为 “切面”)与业务代码分离,在不修改源代码的前提下,动态为目标方法添加增强逻辑,完美解决了这一问题。

2. AOP 核心概念与底层原理

(1)必懂术语
术语含义
连接点(Joinpoint)被拦截的对象(Spring 中仅支持方法作为连接点)
切入点(Pointcut)定义 “拦截哪些方法” 的规则(如所有 ServiceImpl 的 save 方法)
通知(Advice)拦截后执行的增强逻辑(分 5 种类型)
切面(Aspect)切入点 + 通知的组合(核心是 “对谁增强、增强什么”)
织入(Weaving)将切面逻辑注入目标对象,生成代理对象的过程
(2)5 种通知类型
  • 前置通知(@Before):目标方法执行前触发(如日志记录 “方法开始执行”)
  • 后置通知(@AfterReturning):目标方法成功执行后触发(如记录 “方法执行耗时”)
  • 异常通知(@AfterThrowing):目标方法抛出异常时触发(如捕获异常并告警)
  • 最终通知(@After):无论目标方法成功 / 失败,都会触发(如释放资源)
  • 环绕通知(@Around):包裹目标方法,可在执行前后自定义逻辑(需手动调用目标方法)
(3)底层实现

Spring AOP 基于动态代理实现,自动选择代理方式:

  • JDK 动态代理:若目标对象实现接口,通过Proxy类生成接口代理对象
  • CGLIB 代理:若目标对象无接口,通过继承目标类生成代理对象

3. AOP 实战:两种实现方式

(1)注解方式(推荐)

步骤 1:引入依赖在 Maven 的pom.xml中添加 AOP 核心依赖:

<dependencies><!-- Spring核心 --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.2.RELEASE</version></dependency><!-- AOP联盟规范 --><dependency><groupId>aopalliance</groupId><artifactId>aopalliance</artifactId><version>1.0</version></dependency><!-- AspectJ织入器 --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.3</version></dependency>
</dependencies>

步骤 2:编写切面类@Aspect声明切面,用@Before等注解定义通知:

@Component  // 交给Spring管理
@Aspect     // 标记为切面类
public class LogAspect {// 切入点:匹配com.qcbyjy包下所有ServiceImpl的save开头方法@Pointcut("execution(* com.qcbyjy.*.*ServiceImpl.save*(..))")public void logPointcut() {}// 前置通知:在切入点方法执行前触发@Before("logPointcut()")public void beforeLog() {System.out.println("【前置通知】方法开始执行,时间:" + new Date());}
}

步骤 3:开启 AOP 自动代理在 Spring 配置类或 XML 中开启代理:

@Configuration
@ComponentScan("com.qcbyjy")  // 扫描组件
@EnableAspectJAutoProxy       // 开启AOP自动代理
public class SpringConfig {}
(2)XML 配置方式

若项目仍使用 XML 配置,可通过<aop:config>标签实现:

<!-- 1. 配置目标对象和切面类 -->
<bean id="userService" class="com.qcbyjy.demo2.UserServiceImpl"/>
<bean id="logAspect" class="com.qcbyjy.demo2.LogAspect"/><!-- 2. AOP配置 -->
<aop:config><!-- 切面 = 切入点 + 通知 --><aop:aspect ref="logAspect"><!-- 切入点表达式 --><aop:pointcut id="logPointcut" expression="execution(* com.qcbyjy.*.*ServiceImpl.save*(..))"/><!-- 前置通知 --><aop:before method="beforeLog" pointcut-ref="logPointcut"/></aop:aspect>
</aop:config>

二、JDBC 模板:简化数据库操作

在传统 JDBC 开发中,“加载驱动、创建连接、处理异常、关闭资源” 等模板代码重复且繁琐。Spring 的JdbcTemplate封装了这些细节,让开发者专注于 SQL 逻辑。

1. JDBC 模板核心功能

  • 自动管理数据库连接(获取 / 释放)
  • 支持增删改查(CRUD)操作
  • 内置异常转换(将 SQL 异常转为 Spring 统一异常)
  • 支持结果集映射(自定义RowMapper封装对象)

2. 实战:从配置到 CRUD

(1)环境搭建

依赖引入:除 Spring 核心依赖外,需添加 JDBC 和数据库驱动:

<!-- Spring JDBC -->
<dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.0.2.RELEASE</version>
</dependency>
<!-- MySQL驱动 -->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.6</version>
</dependency>
<!-- Druid连接池(推荐) -->
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.10</version>
</dependency>

配置数据源与 JDBC 模板:通过配置类注入DataSourceJdbcTemplate

@Configuration
public class JdbcConfig {// 1. 配置Druid数据源@Beanpublic DataSource druidDataSource() {DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUrl("jdbc:mysql:///spring_db");dataSource.setUsername("root");dataSource.setPassword("root");return dataSource;}// 2. 配置JDBC模板(依赖数据源)@Beanpublic JdbcTemplate jdbcTemplate(DataSource dataSource) {return new JdbcTemplate(dataSource);}
}
(2)CRUD 操作示例

以 “账户表(account)” 为例,实现增删改查:

@Service
public class AccountService {@Autowiredprivate JdbcTemplate jdbcTemplate;// 1. 新增账户public void addAccount(Account account) {String sql = "insert into account(name, money) values(?, ?)";jdbcTemplate.update(sql, account.getName(), account.getMoney());}// 2. 根据ID查询账户(自定义RowMapper映射结果)public Account getAccountById(Integer id) {String sql = "select * from account where id = ?";return jdbcTemplate.queryForObject(sql, new RowMapper<Account>() {@Overridepublic Account mapRow(ResultSet rs, int rowNum) throws SQLException {Account account = new Account();account.setId(rs.getInt("id"));account.setName(rs.getString("name"));account.setMoney(rs.getDouble("money"));return account;}}, id);}// 3. 查询所有账户public List<Account> getAllAccounts() {String sql = "select * from account";return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Account.class));}
}

三、事务管理:保障数据一致性

在分布式或多操作场景中,事务的 “ACID” 特性是数据安全的关键。Spring 提供声明式事务,无需手动编写startTransaction()/commit(),通过配置或注解即可实现事务控制。

1. 事务核心概念

  • 隔离级别:解决并发问题(如脏读、不可重复读),默认使用数据库隔离级别(DEFAULT
  • 传播行为:定义方法间事务的传递规则(如REQUIRED:当前无事务则新建,有则加入)
  • 只读属性:查询方法设为readOnly=true,优化数据库性能
  • 超时时间:设置事务超时时间(默认无限制)

2. 实战:声明式事务实现

(1)注解方式(推荐)

步骤 1:配置事务管理器JDBC 模板需使用DataSourceTransactionManager

@Configuration
@EnableTransactionManagement  // 开启事务注解支持
public class TransactionConfig {// 事务管理器(依赖数据源)@Beanpublic PlatformTransactionManager transactionManager(DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}
}

步骤 2:添加事务注解在 Service 方法或类上添加@Transactional

@Service
public class TransferService {@Autowiredprivate AccountDao accountDao;// 转账方法:添加事务注解,确保扣款和收款要么同时成功,要么同时失败@Transactional(isolation = Isolation.DEFAULT,  // 隔离级别propagation = Propagation.REQUIRED,  // 传播行为timeout = 5  // 超时时间(秒))public void transfer(String fromName, String toName, double money) {// 1. 扣款(转出方)accountDao.outMoney(fromName, money);// 模拟异常(测试事务回滚)// int a = 1 / 0;// 2. 收款(转入方)accountDao.inMoney(toName, money);}
}
(2)XML 配置方式

通过<tx:advice>和 AOP 配置实现事务:

<!-- 1. 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="druidDataSource"/>
</bean><!-- 2. 事务通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><!-- 对transfer方法添加事务,设置属性 --><tx:method name="transfer" isolation="DEFAULT" propagation="REQUIRED"/><!-- 对查询方法设为只读 --><tx:method name="get*" read-only="true"/></tx:attributes>
</tx:advice><!-- 3. AOP织入:将事务通知应用到目标方法 -->
<aop:config><aop:advisor advice-ref="txAdvice" pointcut="execution(* com.qcbyjy.demo4.*Service.*(..))"/>
</aop:config>

四、总结与最佳实践

  1. AOP 最佳实践

    • 切面类专注于单一职责(如日志切面只处理日志,事务切面只处理事务)
    • 切入点表达式精准匹配(避免过度增强影响性能)
    • 优先使用注解方式(减少 XML 配置,提高开发效率)
  2. JDBC 模板最佳实践

    • 结合连接池使用(如 Druid、HikariCP),避免频繁创建连接
    • 复杂查询使用RowMapper,简单查询用BeanPropertyRowMapper
    • 批量操作使用batchUpdate(),减少 SQL 执行次数
  3. 事务管理最佳实践

    • 事务注解加在 Service 层(而非 Dao 层,确保业务逻辑完整性)
    • 明确设置传播行为(如跨服务调用用REQUIRES_NEW
    • 捕获异常时避免吞掉异常(需抛出RuntimeException触发回滚)

通过掌握 Spring 的 AOP、JDBC 模板与事务管理,开发者可以大幅简化代码、降低耦合,同时保障系统的可维护性和数据一致性。这些技术不仅是 Spring 生态的核心,也是 Java 后端开发的必备技能。

http://www.dtcms.com/a/602488.html

相关文章:

  • 杭州做外贸网站网站编辑工具软件
  • 《C++ Primer》和《Effective C++》哪个更厚?
  • 做海报那个网站好一分钟赚50元的游戏
  • 封装了 Android 权限检查和申请功能 PermissionManager工具类,支持权限检查、申请、说明对话框显示和设置页面引导等功能。
  • 2.GPU 网络架构全栈规划与深度分析:从业务需求到落地优化(H100/H200/B200/GB200 实战视角)
  • 企业网站手机端跳转设置门户cms系统
  • 鞍山58路公交车路线苏州百度seo关键词优化
  • 大储和工商储的差异
  • Windows 终端延迟剖析:从“卡顿感”到毫秒账本
  • wordpress图片自动分页插件下载关键词排名优化工具
  • 17.PHP基础-数组
  • 【MyBatis笔记】 - 4 - 缓存 + 逆向工程 + 分页插件
  • jsp和.net做网站的区别好大夫在线医生免费咨询
  • 目标客户精准营销品牌seo推广咨询
  • 企业网站asp一篇网站设计小结
  • 数据库概论实验(黑龙江大学)
  • HCI 数据格式
  • 用wordpress仿站企业宣传方案模板
  • 使用Netlify部署前端项目
  • 网站设计结构图用什么做丝芭传媒有限公司
  • pagehide/beforeunload / unload / onUnmounted 执行顺序与navigator.sendBeacon使用陷阱详解
  • 解决若依框架点击菜单无效的问题(或者main主体白板)vue3版本
  • 回溯-22括号生成
  • 如何做网站卖衣服第一营销网
  • 怎么写网站建设的说明线上设计师是什么意思
  • 力扣(LeetCode) ——43.字符串相乘(C++)
  • 哪里有做网站服务世安建设有限网站
  • 目前哪些企业需要做网站建设的呢企业网站优化兴田德润优惠
  • strchr函数
  • 做图书网站赚钱么关于网站建设的名言