Spring AOP概念与应用学习

Spring AOP概念与应用学习

介绍

本篇文章将通过实现事务控制示例来学习AOP思想。示例代码仓库为:Spring AOP概念与应用学习(gitee.com)

参考资料

文中示例代码使用的是B站UP主程序员的梦姐姐呀的视频:10分钟后,再也不用死记硬背SpringAOP八股了_哔哩哔哩_bilibili中展示的代码,我加上了自己的理解注解,以此来帮助其他读者更好的理解每一处代码的作用,如果侵权,可联系本人删除。

相关概念

AOP(面向切面编程)相关概念:
1.切面: 拦截处理类,示例中指的是:TransactionManagerHandler
2.切入点: 拦截规则,分别有 前置:before后置:after-returning异常:after-throwing最终:after
3.连接点: 具体背拦截到的方法,示例中指的是:service.impl.UserServiceImpl.insert()
4.通知: 在不同的场景下拦截的功能,即在不同拦截规则中具体实现的逻辑;
5.织入: 由spring完成,切面类包裹住对象,创建出代理对象。

两种形式

XML文件配置实现

XML文件配置实现AOP示例项目文件结构如下图所示:
xml配置实现项目结构

其中lib库中使用到的是各类jar包,src目录下则是示例代码。

如果项目使用xml文件进行配置比较多,则在原有的项目逻辑上通过新增xml文件来编写AOP配置则可以实现通过AOP的方式来实现事务控制。具体的xml文件applicationContext.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    <bean id="UserService" class="service.impl.UserServiceImpl"></bean>
    <bean id="TransactionManager" class="service.TransactionManagerHandler"/>
    <aop:config>
        <!--
        AOP相关概念:
            1.切面:拦截处理类,示例中指的是:TransactionManagerHandler
            2.切入点:拦截规则,分别有 前置:before;后置:after-returning;异常:after-throwing;最终:after
            3.连接点:具体背拦截到的方法,示例中指的是:service.impl.UserServiceImpl.insert()
            4.通知:在不同的场景下拦截的功能,即在不同拦截规则中具体实现的逻辑
            5.织入:由spring完成,切面类包裹住对象,创建出代理对象
        -->
        <!--配置切面-->
        <aop:aspect ref="TransactionManager">
            <!--配置切入点,pt是pointcut的别称-->
            <aop:pointcut id="pt" expression="execution(public void service.impl.UserServiceImpl.insert())"/>
            <!--在切入点的各个拦截规则中配置通知-start-->
            <!--表示在pt所指代的方法执行之前执行method中指定的方法,这里执行begin方法-->
            <aop:before method="begin" pointcut-ref="pt"/>
            <!--表示在pt所指代的方法执行完成正常返回之后执行method中指定的方法,这里执行commit方法-->
            <aop:after-returning method="commit" pointcut-ref="pt"/>
            <!--表示在pt所指代的方法执行发生异常时执行method中指定的方法,这里执行rollback方法-->
            <aop:after-throwing method="rollback" pointcut-ref="pt"/>
            <!--表示在pt所指代的方法执行最后执行method中指定的方法,这里执行closeSession方法-->
            <aop:after method="closeSession" pointcut-ref="pt"/>
            <!--在切入点的各个拦截规则中配置通知-end-->
        </aop:aspect>
    </aop:config>
</beans>

事务控制具体实现逻辑类TransactionManagerHandler.class代码如下:

package service;

public class TransactionManagerHandler {
    public void begin(){
        System.out.println("开启事务!");
    }
    public void commit(){
        System.out.println("提交事务!");
    }
    public void rollback(){
        System.out.println("回滚事务!");
    }
    public void closeSession(){
        System.out.println("关闭链接!");
    }
}

通过执行AopTest.class中的测试代码即可得到效果,效果如下:
测试结果
由此可见事务控制逻辑按照实现配置好的顺序执行完成,通过在逻辑代码中抛出测试异常来测试事务回滚逻辑是否实现,修改后的代码如下:

package service.impl;
import service.UserService;
public class UserServiceImpl implements UserService {
    @Override
    public void insert() {
        System.out.println("执行插入逻辑!");
        throw new RuntimeException("测试");
    }
}

重新运行测试方法得到如下结果:
测试结果
由此可见异常回滚逻辑也可正常执行。

注解配置实现

注解配置实现AOP示例项目文件结构如下图所示:
注解配置项目结构
其中lib库中使用到的是各类jar包,src目录下则是示例代码。

注解配置实现与xml文件配置实现得最大不同点在于移除了繁琐的xml配置,通过SpringConfig.class配置类来完成AOP的基础配置,配置类SpringConfig.class内容如下所示:

package config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
//声明这个是配置类
@Configuration
//配置要扫描的包,这里配置扫描service包,如果不配置,由于没有xml文件进行配置,则会造成pointcut无法识别到bean:UserService
@ComponentScan("service")
//启用aop代理注解
@EnableAspectJAutoProxy
public class SpringConfig {
}

切面控制类中需要添加AOP相关注解来实现具体的配置,修改后的切面控制类TransactionManagerHandler.class文件内容如下:

package service;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
//将类交由Spring容器进行管理
@Component
//表明该类是切面控制类
@Aspect
public class TransactionManagerHandler {
    @Pointcut("execution(public void service.impl.UserServiceImpl.insert())")
    public void pointcut(){}
    @Before("pointcut()")
    public void begin() {
        System.out.println("开启事务!");
    }
    @AfterReturning("pointcut()")
    public void commit() {
        System.out.println("提交事务!");
    }
    @AfterThrowing("pointcut()")
    public void rollback() {
        System.out.println("回滚事务!");
    }
    @After("pointcut()")
    public void closeSession() {
        System.out.println("关闭链接!");
    }
}

业务逻辑代码实现类UserServiceImpl.class中需要添加@Service注解,修改后的代码如下:

package service.impl;
import org.springframework.stereotype.Service;
import service.UserService;
@Service
public class UserServiceImpl implements UserService {
    @Override
    public void insert() {
        System.out.println("执行插入逻辑!");
    }
}

测试类中由于不再使用xml文件进行配置,因此需要对测试类AopTest.class代码进行修改,修改后的代码如下:

package test;
import config.SpringConfig;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import service.UserService;
public class AopTest {
    @Test
    public void testInsert() {
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        UserService userService = context.getBean(UserService.class);
        userService.insert();
    }
}

测试类执行结果如下:
测试结果
由此可见事务控制逻辑按照实现配置好的顺序执行完成,测试异常情况事务回滚逻辑执行结果如下:
测试结果
由此可见异常回滚逻辑也可正常执行。

结束语

通过简单的两个小的事务控制示例项目可以充分理解AOP思想的应用,文中如果有错误的地方欢迎各位读者指出,同时也感谢B站UP主程序员的梦姐姐呀的知识分享。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

think_mzs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值