千家信息网

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的使用方法"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

0