文章详情

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

请输入下面的图形验证码

提交验证

短信预约提醒成功

Spring中的AOP编程怎么应用

2023-07-05 20:51

关注

本文小编为大家详细介绍“Spring中的AOP编程怎么应用”,内容详细,步骤清晰,细节处理妥当,希望这篇“Spring中的AOP编程怎么应用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

AOP 概述

AOP 为 Aspect Oriented Programming 的缩写,是面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP 是 OOP 的延续,是软件开发中的一个热点,也是 Spring 框架中的一个重要内容,是函数式编程的一种衍生范型

AOP 可以分离业务代码和关注点代码(重复代码),在执行业务代码时,动态的注入关注点代码。切面就是关注点代码形成的类。Spring AOP 中的动态代理主要有两种方式,JDK 动态代理和 CGLIB 动态代理。JDK 动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口

Spring中的AOP编程怎么应用

AOP 实现分类

AOP 要达到的效果是,保证开发者不修改源代码的前提下,去为系统中的业务组件添加某种通用功能,按照 AOP 框架修改源代码的时机,可以将其分为两类:

AOP 术语

通知的类型

Spring 方面可以使用下面提到的五种通知工作:

通知描述
前置通知在一个方法执行之前,执行通知。
最终通知在一个方法执行之后,不考虑其结果,执行通知。
后置通知在一个方法执行之后,只有在方法成功完成时,才能执行通知。
异常通知在一个方法执行之后,只有在方法退出抛出异常时,才能执行通知。
环绕通知在一个方法调用之前和之后,执行通知。

基于 Aspectj 实现 AOP 操作

基于 Aspectj 实现 AOP 操作,经历了下面三个版本的变化,注解版是我们最常用的。

切入点表达式

作用:声明对哪个类中的哪个方法进行增强

语法:

execution([访问权限修饰符] 返回值 [ 类的全路径名 ] 方法名 (参数列表)[异常])

Spring中的AOP编程怎么应用

第一版:基于xml(aop:config)配置文件

使用 Spring AOP 接口方式实现 AOP, 可以通过自定义通知来供 Spring AOP 识别对应实现的接口是:

  1. 前置通知:MethodBeforeAdvice

  2. 返回通知:AfterReturningAdvice

  3. 异常通知:ThrowsAdvice

  4. 环绕通知:MethodInterceptor

实现步骤:

定义业务接口

package cn.kgc.spring05.entity;public interface Teacher {    String teachOnLine(String course);    String teachOffLine(Integer course);}

2、定义实现类

package cn.kgc.spring05.entity;public class TeacherA implements Teacher{    @Override    public String teachOnLine(String course) {        System.out.println("TeacherA开始"+course+"课程线上教学");        if(course.equals("java")){            throw new RuntimeException("入门到放弃!");        }        return course+"课程线上教学";    }    @Override    public String teachOffLine(Integer course) {        System.out.println("TeacherA开始"+course+"课程线下教学");        return course+"课程线下教学";    }}

3、实现接口定义通知类

前置通知类

package cn.kgc.spring05.advice;import org.springframework.aop.MethodBeforeAdvice;import java.lang.reflect.Method;//前置通知public class MyMethodBeforeAdvice implements MethodBeforeAdvice {    @Override    public void before(Method method, Object[] objects, Object o) throws Throwable {        System.out.println("------------spring aop 前置通知------------");    }}

后置通知类

package cn.kgc.spring05.advice;import org.springframework.aop.AfterReturningAdvice;import java.lang.reflect.Method;public class MyAfterReturnAdvice implements AfterReturningAdvice {    @Override    public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {        System.out.println("------------spring aop 后置通知------------");    }}

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/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">    <!--托管通知-->    <bean id="after" class="cn.kgc.spring05.advice.MyAfterReturnAdvice"></bean>    <bean id="before" class="cn.kgc.spring05.advice.MyMethodBeforeAdvice"></bean>    <bean id="teacherA" class="cn.kgc.spring05.entity.TeacherA"></bean>    <!--AOP的配置-->    <aop:config>        <!--切点表达式-->        <aop:pointcut id="pt" expression="execution(* *(..))"/>        <aop:advisor advice-ref="before" pointcut-ref="pt"></aop:advisor>        <aop:advisor advice-ref="after" pointcut-ref="pt"></aop:advisor>    </aop:config></beans>

5、测试

package cn.kgc.spring05;import cn.kgc.spring05.entity.Teacher;import junit.framework.TestCase;import junit.framework.TestSuite;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:spring-config.xml")public class AppTest{    @Autowired    Teacher teacher;    @Test    public void teachOnLine() {        System.out.println(teacher.getClass());        String s = teacher.teachOnLine("java");        System.out.println("s = " + s);    }}

6、运行结果

Spring中的AOP编程怎么应用

第二版:基于xml(aop:aspect)配置文件

基于 xml(aop:config) 配置文件的方式,增加几个通知,就会创建几个通知类,那我们能否将这些通知类写在一个类中呢?下面就让我来带你们找到解决之法!

配置 AspectJ 标签解读表

Spring中的AOP编程怎么应用

实现步骤:

1、定义业务接口

package cn.kgc.spring05.entity;public interface Teacher {    String teachOnLine(String course);    String teachOffLine(Integer course);}

2、定义实现类

package cn.kgc.spring05.entity;public class TeacherA implements Teacher{    @Override    public String teachOnLine(String course) {        System.out.println("TeacherA开始"+course+"课程线上教学");        if(course.equals("java")){            throw new RuntimeException("入门到放弃!");        }        return course+"课程线上教学";    }    @Override    public String teachOffLine(Integer course) {        System.out.println("TeacherA开始"+course+"课程线下教学");        return course+"课程线下教学";    }}

3、实现接口定义通知类

package cn.kgc.spring05.advice;public class AllAdvice {    public void before(){System.out.println("------------前置通知--------------");}    public void afterReturning(){System.out.println("------------后置通知--------------");}    public void afterThrowing(){System.out.println("------------异常通知--------------");}    public void after(){System.out.println("------------最终通知--------------");}    public void around(){System.out.println("------------环绕通知--------------");}}

4、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/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">    <!--托管通知-->    <bean id="all" class="cn.kgc.spring05.advice.AllAdvice"></bean>    <bean id="teacherA" class="cn.kgc.spring05.entity.TeacherA"></bean>    <!--AOP的配置-->    <aop:config>        <!--切点表达式-->        <aop:pointcut id="pt" expression="execution(* *(String))"/>        <aop:aspect ref="all">            <aop:before method="before" pointcut-ref="pt"></aop:before>            <aop:after-returning method="afterReturning" pointcut-ref="pt"></aop:after-returning>            <aop:after-throwing method="afterThrowing" pointcut-ref="pt"></aop:after-throwing>            <aop:after method="after" pointcut-ref="pt"></aop:after><!--            <aop:around method="around" pointcut-ref="pt"></aop:around>-->        </aop:aspect>    </aop:config></beans>

5、测试

package cn.kgc.spring05.advice;import cn.kgc.spring05.entity.Teacher;import junit.framework.TestCase;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:spring-config2.xml")public class AllAdviceTest{    @Autowired    Teacher teacher;    @Test    public void test01() {        System.out.println(teacher.getClass());        String s = teacher.teachOnLine("java");        System.out.println("s = " + s);    }}

6、运行结果

Spring中的AOP编程怎么应用

第三版:基于注解实现通知

@Aspect 注解将此类定义为切面。
@Before 注解用于将目标方法配置为前置增强(前置通知)。
@AfterReturning 注解用于将目标方法配置为后置增强(后置通知)。
@Around 定义环绕增强(环绕通知)
@AfterThrowing 配置异常通知
@After 也是后置通知,与 @AfterReturning 很相似,区别在于 @AfterReturning 在方法执行完毕后进行返回,可以有返回值。@After 没有返回值。

实现步骤:

定义业务接口

package cn.kgc.spring05.entity;public interface Teacher {    String teachOnLine(String course);    String teachOffLine(Integer course);}

2、定义注解

package cn.kgc.spring05.advice;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface AnnoAdvice {}

3、定义实现类

package cn.kgc.spring05.entity;import cn.kgc.spring05.advice.AnnoAdvice;import org.springframework.stereotype.Component;@Componentpublic class TeacherA implements Teacher{    @Override    @AnnoAdvice    public String teachOnLine(String course) {        System.out.println("TeacherA开始"+course+"课程线上教学");        if(course.equals("java")){            throw new RuntimeException("入门到放弃!");        }        return course+"课程线上教学";    }    @Override    @AnnoAdvice    public String teachOffLine(Integer course) {        System.out.println("TeacherA开始"+course+"课程线下教学");        return course+"课程线下教学";    }}

4、实现接口定义切面类

首先在类上面添加 @Aspect 注解,将该类转化为切面类,再在类中的各个方法上面使用各自的 “通知” 注解即可实现。

package cn.kgc.spring05.advice;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.*;import org.springframework.stereotype.Component;@Component@Aspectpublic class AllAdvice {    @Pointcut("@annotation(AnnoAdvice)")    public void point(){}    @Before("point()")    public void before(){System.out.println("------------前置通知--------------");}    @AfterReturning("point()")    public void afterReturning(){System.out.println("------------后置通知--------------");}    @AfterThrowing("point()")    public void afterThrowing(){System.out.println("------------异常通知--------------");}    @After("point()")    public void after(){System.out.println("------------最终通知--------------");}    @Around("point()")    public Object aroundAdvice(ProceedingJoinPoint joinPoint){        Object proceed = null;        try {            System.out.println("----------spring aop 环绕 前通知-----------");            proceed = joinPoint.proceed();            System.out.println("----------spring aop 环绕 后通知-----------");        } catch (Throwable throwable) {            throwable.printStackTrace();            System.out.println("----------spring aop 环绕 异常通知-----------");        }finally {            System.out.println("----------spring aop 环绕 最终通知-----------");        }        return proceed;    }}

5、XML 配置方式

开启包扫描和aspectj自动代理

<?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"       xmlns:context="http://www.springframework.org/schema/context"       xsi:schemaLocation="http://www.springframework.org/schema/beans       http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">    <!--开启包扫描-->    <context:component-scan base-package="cn.kgc.spring05"></context:component-scan>    <!--开启aspectj自动代理-->    <aop:aspectj-autoproxy></aop:aspectj-autoproxy></beans>

6、测试

package cn.kgc.spring05.advice;import cn.kgc.spring05.entity.Teacher;import junit.framework.TestCase;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:spring-config3.xml")public class AllAdviceTest{    @Autowired    Teacher teacher;    @Test    public void test01() {        System.out.println(teacher.getClass());        String s = teacher.teachOnLine("html");        System.out.println("s = " + s);    }}

7、运行效果

Spring中的AOP编程怎么应用

读到这里,这篇“Spring中的AOP编程怎么应用”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

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

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

软考中级精品资料免费领

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

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

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

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

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

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

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