文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

SpringAOP 设置注入的实现步骤

2024-04-02 19:55

关注

AOP_面向切面编程初步了解

让我们先想象一个场景,你正在编写一个项目,在开发过程中的多个模块都有某段重复的代码,于是你选择将其抽象成一个方法,然后在需要的地方调用这个方法,当需要修改这段代码时只需要修改这个方法就行。有一天,你的Boss给了新的需求,需要再抽象出一个方法,然后再在各个需要这个方法的模块调用这个方法,这可能就让你头疼了,需要修改大量的代码,于是会想,能不能不修改源代码为系统业务添加某种功能呢?幸运的是,AOP可以很好的解决这个问题。

简单介绍

AOP:保证开发者不修改源代码的前提下,去为系统中的业务组件添加某种通用功能,本质是由AOP框架修改业务组件的多个方法的源代码,我们将其分为两类:

AOP 框架在编译阶段对程序源代码进行修改,生成了静态的 AOP 代理类(生成的*.class文件已经被改掉了,需要使用特定的编译器),比如 AspectJ。

AOP 框架在运行阶段对动态生成代理对象(在内存中以 JDK 动态代理,或 CGlib 动态地生成 AOP 代理类),如 SpringAOP。

详细说明

Spring 的通知类型

名称 标签 说明
前置通知 < aop:before > 用于配置前置通知。指定增强的方法在切入点方法之前执行
后置通知 < aop:after-returning > 用于配置后置通知。指定增强的方法在切入点方法之后执行
环绕通知 < aop:around > 用于配置环绕通知。指定增强的方法在切入点方法之前和之后都执行
异常通知 < aop:throwing > 用于配置异常抛出通知。指定增强的方法在出现异常时执行
最终通知 < aop:after > 用于配置最终通知。无论增强方式执行是否有异常都会执行

实战演练

导入依赖包


    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.3.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.6</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
        <dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

创建一个增强类以及其接口

增强类接口:


public interface VisitService {
    //用于实现前置通知,后置通知,异常通知,最终通知
    void visit(String str) throws Exception;

    //用于实现环绕通知
    void around();
}

增强类:


public class VisitServiceImpl implements VisitService {
    //前置,后置,最终,异常通知的增强类
    public void visit(String str) throws Exception{
        System.out.println(str);
        if(!str.equalsIgnoreCase("agree")){
            throw new Exception("非法访问");
        }
    }
    //环绕通知的增强类
    public void around() {
        System.out.println("环绕通知");
    }
}

创建一个切面类


public class VisitAspect {
    //前置通知
    public void visitBefore(JoinPoint joinPoint){
        System.out.println("口令:");
    }
    //最终通知,无论是否报错,都执行
    public void visitAfter(JoinPoint joinPoint){
        System.out.println("输入完成");
    }
    //后置通知报错不执行
    public void visitSuccess(JoinPoint joinPoint){
        System.out.println("请求成功,欢迎");
    }
    //异常通知,报错后执行
    public void visitThrow(JoinPoint joinPoint, Throwable ex){
        System.out.println("请求失败,拒绝");
    }
    //环绕通知,如果报错只执行前一句
    public Object visitAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
        System.out.println("-------环绕-------");
        Object obj = proceedingJoinPoint.proceed();
        System.out.println("-------环绕-------");
        return obj;
    }
}

配置xml文件,需要添加第三方约束


    <bean id="userDao" class="Spring_AOP.service.impl.VisitServiceImpl"></bean>
    <bean id="aspect" class="Spring_AOP.service.VisitAspect"></bean>
    
    <aop:config>
        <aop:pointcut id="pointcut" expression="execution(* Spring_AOP.service.impl.VisitServiceImpl.visit(..))"/>
        <aop:pointcut id="pointcut1" expression="execution(* Spring_AOP.service.impl.VisitServiceImpl.around())"/>
        <aop:aspect ref="aspect">
             <aop:before method="visitBefore" pointcut-ref="pointcut"></aop:before>
             <aop:after method="visitAfter" pointcut-ref="pointcut"></aop:after>
             <aop:after-returning method="visitSuccess" pointcut-ref="pointcut"></aop:after-returning>
             <aop:around method="visitAround" pointcut-ref="pointcut1"></aop:around>
             <!-- 报错后执行aop:after-throwing -->
             <aop:after-throwing method="visitThrow" pointcut-ref="pointcut" throwing="ex"></aop:after-throwing>
         </aop:aspect>
    </aop:config>

注,对于execution()
1、execution(): 表达式主体 (必须加上execution)。
2、第一个* 号:表示返回值类型,* 号表示所有的类型。
3、包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,cn.smd.service.impl包、子孙包下所有类的方法。
4、第二个* 号:表示类名,* 号表示所有的类。
5、* (..):最后这个星号表示方法名,* 号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。
书写的注意事项:execution(* cn.smd.service.impl..(..))

创建一个测试类


 public class visitTest {
    @Test
    public void VisitTest(){
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext_AOP.xml");
        VisitService visitService = app.getBean(VisitService.class);
        try {
            visitService.visit("agree");
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            visitService.visit("ok");
        } catch (Exception e) {
            e.printStackTrace();
        }
        visitService.around();
    }
}

测试运行

口令:
agree
请求成功,欢迎
输入完成
口令:
ok
请求失败,拒绝
输入完成
-------环绕-------
环绕通知
-------环绕-------

总结

以上就是SpringAOP 设置注入的实现步骤的详细内容,更多关于SpringAOP 设置注入的资料请关注编程网其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯