SpringBean中Aop的使用方法
发表于:2025-02-08 作者:千家信息网编辑
千家信息网最后更新 2025年02月08日,本篇内容主要讲解"SpringBean中Aop的使用方法",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"SpringBean中Aop的使用方法"吧!Spri
千家信息网最后更新 2025年02月08日SpringBean中Aop的使用方法
本篇内容主要讲解"SpringBean中Aop的使用方法",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"SpringBean中Aop的使用方法"吧!
SpringAOP
什么是Aop编程
Aop面向切面编程,在方法之前和之后实现处理 应用场景在于:日志打印、事务实现、安全等。
因为AOP可以解决我们程序上的代码冗余问题
Spring的AOP
前置通知
后置通知
环绕通知
运行通知
异常通知
Aop编程底层的原理
动态代理技术
基于Jdk实现InvocationHandler 底层使用反射技术
基于CGLIB实现 字节码技术
基于注解方式启动Aop
org.springframework spring-context 5.0.5.RELEASE org.aspectj aspectjweaver 1.8.13
日志AOP
@Aspect//定义切面类@Component//注入spring容器@EnableAspectJAutoProxy//开启AOPpublic class LogAop { //定义切入点,表示开始拦截的入口 @Pointcut("execution (* com.xuyu.service..*.*(..))") public void logAop(){ } @Before("logAop()") public void doBefor(){ System.out.println("前置通知....在调用方法之前拦截"); } @After("logAop()") public void doAfter(){ System.out.println("后置通知....在调用方法之后拦截"); }}
Config
@Configuration@ComponentScan(basePackages = {"com.xuyu.service","com.xuyu.aop"})public class MyConfig {}
service
@Componentpublic class OrderService { public void addOrder(){ System.out.println("执行目标方法...."); }}
启动类
public class App { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class); OrderService orderService = applicationContext.getBean("orderService", OrderService.class); orderService.addOrder(); }}
执行结果
前置通知....在调用方法之前拦截
执行目标方法....
后置通知....在调用方法之后拦截
我们开始分析下源码
所以我们可以直接使用@Import注解把AspectJAutoProxyRegistrar这个类注入IOC容器中
@Import(AspectJAutoProxyRegistrar.class)
等价于这个注解
@EnableAspectJAutoProxy//开启AOP
完整的五个通知
@Aspect//定义切面类@Component//注入spring容器@EnableAspectJAutoProxy//开启AOPpublic class LogAop { //定义切入点,表示开始拦截的入口@Pointcut("execution (* com.xuyu.service..*.*(..))") public void logAop(){ } @Before("logAop()") public void doBefore(){ System.out.println("前置通知....在调用方法之前拦截"); } @After("logAop()") public void doAfter(){ System.out.println("后置通知....在调用方法之后拦截"); } @AfterReturning("logAop()") public void around(JoinPoint joinpoint) throws Throwable { String name = joinpoint.getSignature().getName(); System.out.println("返回通知...."+name); } @AfterThrowing("logAop()") public void afterThrowing(JoinPoint joinPoint) { System.out.println("异常通知...."); } @Around("logAop()") public void doAround(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("环绕通知,在目标方法之前处理...."); joinPoint.proceed();//执行目标方法 System.out.println("环绕通知,在目标方法之后处理...."); }}
打印结果
环绕通知,在目标方法之前处理....
前置通知....在调用方法之前拦截
目标方法执行....
环绕通知,在目标方法之后处理....
后置通知....在调用方法之后拦截
返回通知....addOrder
springBoot手动事务实现方式
手动begin commit rollback
@Componentpublic class TransactionalUtils { //TransactionAspectSupport currentTransactionStatus().setRollbackOnly(); /** * 获取当前事务管理器 */ @Autowired private DataSourceTransactionManager dataSourceTransactionManager; public TransactionStatus begin() { TransactionStatus transaction = dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute()); System.out.println("获取当前的事务>>>>>"); return transaction; } /** * 提交事务 */ public void commit(TransactionStatus transactionStatus) { System.out.println("提交当前的事务>>>>>"); dataSourceTransactionManager.commit(transactionStatus); } public void rollback(TransactionStatus transactionStatus) { System.out.println("回滚当前的事务>>>>>"); dataSourceTransactionManager.rollback(transactionStatus); }}
@Servicepublic class OrderService { @Autowired private OrderInfoMapper orderInfoMapper; @Autowired private TransactionalUtils transactionalUtils; public int addOrderInfo(int j) { TransactionStatus begin = transactionalUtils.begin(); try { int i = orderInfoMapper.addOrderInfo(); int result = 1 / j; transactionalUtils.commit(begin); } catch (Exception e) { e.printStackTrace(); transactionalUtils.rollback(begin); } return 1; }
手动begin commit rollback代码会冗余,所以我们使用AOP重构下手动事务
使用SpringAop实现重构实现声明式事务
@Aspect@Component@Scope("prototype")//单例会有问题,这里设置为多例public class TransactionalAop { //Aspect 定义切点类 @Autowired private TransactionalUtils transactionalUtils; /** * @Pointcut 定义切入点 */ @Pointcut("execution (* com.mayikt.service..*.*(..))") public void transactionalAop() { } @Around("transactionalAop()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { // 获取方法名称 String methodName = joinPoint.getSignature().getName(); // 获取目标对象 Class> classTarget = joinPoint.getTarget().getClass(); // 获取目标对象类型 Class>[] par = ((MethodSignature) joinPoint.getSignature()).getParameterTypes(); // 获取目标对象方法 Method objMethod = classTarget.getMethod(methodName, par); // 判断该目标方法上是否有加上自定义事务注解 ExtTransactional extTransactional = objMethod.getDeclaredAnnotation(ExtTransactional.class); if (extTransactional == null) { return joinPoint.proceed();// 执行目标方法 } TransactionStatus begin = transactionalUtils.begin(); try { System.out.println(">>>>环绕通知之前执行...>>>>>>"); Object proceed = joinPoint.proceed();// 执行目标方案 System.out.println(">>>>环绕通知之后执行...>>>>>>"); transactionalUtils.commit(begin); return proceed; } catch (Exception e) { // 目标方法抛出异常的情况下 回滚当前事务 transactionalUtils.rollback(begin); return 0; } }}
@Target({ElementType.METHOD, ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface ExtTransactional {}
@ExtTransactionalpublic int addOrderInfo(int j) { int i = orderInfoMapper.addOrderInfo(); return i;}
注意的问题 如果在service 层 抛出异常的情况下 最好使用 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
到此,相信大家对"SpringBean中Aop的使用方法"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
方法
目标
事务
手动
注解
使用方法
切入点
切面
容器
对象
技术
问题
处理
编程
代码
入口
内容
冗余
前处理
底层
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
网络安全哪个二本
冒充中国网络安全机构
网络安全检讨反思军人
数据库加乐观锁异常处理
重庆安卓应用软件开发怎样收费
电影神秘的家庭服务器
tbc怀旧服服务器人口状况
qq邮箱发送服务器地址
软件开发者的权利和义务
视图如何实现数据库安全性
石油石化网络安全定级标准
1230v3服务器
阿拉德之怒服务器异常是什么意思
南昌二附院网络安全协调会
软件开发公司哪种品牌好
江苏智慧城管软件开发公司
数据库的增 用到什么技术
软件开发属于几级学科
sql 数据库附加
oracle数据库 论文
网络安全中心图片
jdbc生成数据库
上海网络技术分类工程
火车头采集的数据库在哪里
goldendb数据库安装
数据库访问其他地址的表
16亿q绑数据库泄露
猫咪很可爱服务器不可用
创建mydb数据库正确的命令是
软件开发黑客技术