Spring学习通过AspectJ注解方式实现AOP操作

目录
  • Spring注解AspectJ操作AOP
    • 一、被增强类
    • 二、增强类
    • 三、进行通知的配置
      • 1. spring 配置文件中,开启扫描。
      • 2. 使用注解创建 User 和 UserProxy 对象
      • 3. 在增强类上使用注解 @Aspect
      • 4. spring配置,开启生成代理对象
      • 5. 配置不同类型的通知
    • 四、抽取相同切入点
    • 五、多个增强类的优先级

Spring注解AspectJ操作AOP

一、被增强类

新建一个被增强的类 User,下面有个 add() 方法。

package com.pingguo.spring5.aopanno;
public class User {
    public void add() {
        System.out.println("add ... ...");
    }
}

二、增强类

创建增强类,用于编写增强的逻辑。

package com.pingguo.spring5.aopanno;public class UserProxy { // 前置通知 public void before() { System.out.println("before ... ..."); }}package com.pingguo.spring5.aopanno;
public class UserProxy {
    // 前置通知
    public void before() {
        System.out.println("before ... ...");
    }
}

三、进行通知的配置

1. spring 配置文件中,开启扫描。

<?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:context="http://www.springframework.org/schema/context"
       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 http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--开启注解扫描-->
    <context:component-scan base-package="com.pingguo.spring5.aopanno"></context:component-scan>
    <!--开启 Aspect 生成代理对象-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

这里创建了 2 个名称空间:

xmlns:context:开启注解扫描用

xmlns:aop:开启生成代理对象

2. 使用注解创建 User 和 UserProxy 对象

// 被增强类
@Component
public class User {
    public void add() {
        System.out.println("add ... ...");
    }
}
// 增强类
@Component
public class UserProxy {
    // 前置通知
    public void before() {
        System.out.println("before ... ...");
    }
}

使用 @Component 注解。

3. 在增强类上使用注解 @Aspect

// 增强类
@Component
@Aspect
public class UserProxy {
    // 前置通知
    public void before() {
        System.out.println("before ... ...");
    }
}

4. spring配置,开启生成代理对象

<!--开启 Aspect 生成代理对象-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

在配置文件中增加配置。

5. 配置不同类型的通知

在上一篇文章中提到了 5 种不同类型的通知,在这里使用不同的注解来配置不同的类型。

(1)@Before

表示作为前置通知。

// 增强类
@Component
@Aspect
public class UserProxy {
    // 前置通知
    @Before(value = "execution(* com.pingguo.spring5.aopanno.User.add(..))")
    public void before() {
        System.out.println("before ... ...");
    }
}

@Before 注解里的 value 值就是切入点表达式,表示要对哪个类里面的哪个方法进行增强。

新建一个测试类的方法运行一下:

public class TestAop {
    @Test
    public void testAopanno() {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean1.xml");
        User user = context.getBean("user", User.class);
        user.add();
    }
}

运行结果:

before ... ...
add ... ...
Process finished with exit code 0

可以看出,先执行了前置增强 before() 方法,再执行了 add() 方法。

(2)@After

表示作为后置通知。而且不管有没有异常都会执行(文末示例)。

// 后置通知
    @After(value = "execution(* com.pingguo.spring5.aopanno.User.add(..))")
    public void after() {
        System.out.println("After ... ...");
    }

运行结果:

add ... ...
After ... ...
Process finished with exit code 0

(3)@AfterReturning

另外,还有个注解 @AfterReturning,也是在被增强之后执行,不过可以拿到被增强方法的返回值。

修改被增强类的 add() 方法:

// 被增强类
@Component
public class User {
    public String add() {
        System.out.println("add ... ...");
        return "add()方法返回值";
    }
}

修改增强类:

@AfterReturning(value = "execution(* com.pingguo.spring5.aopanno.User.add(..))", returning = "result")
    public void afterReturning(String result) {
        System.out.println("AfterReturning ... ..." + result);
    }

这里 returning = "result",result 就是定义的获取到的变量,下面可以使用。

运行测试:

add ... ...
AfterReturning ... ...add()方法返回值
Process finished with exit code 0

(4)@Around

表示环绕通知。

// 环绕通知
    @Around(value = "execution(* com.pingguo.spring5.aopanno.User.add(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕之前 ... ...");
        // 被增强的方法执行
        proceedingJoinPoint.proceed();
        System.out.println("环绕之后 ... ...");
    }

运行结果:

环绕之前 ... ...
add ... ...
环绕之后 ... ...
Process finished with exit code 0

(5)@AfterThrowing

表示环绕通知。

现在让 add() 方法抛异常:

// 被增强类
@Component
public class User {
    public void add() {
        int i = 1/0;
        System.out.println("add ... ...");
    }
}

使用 @AfterThrowing:

//  异常通知
    @AfterThrowing(value = "execution(* com.pingguo.spring5.aopanno.User.add(..))")
    public void afterThrowing() {
        System.out.println("AfterThrowing ... ...");
    }

运行测试:

AfterThrowing ... ...
java.lang.ArithmeticException: / by zero

注意,在上面提到的 @After,不管有没有异常都会执行。

//  异常通知
    @AfterThrowing(value = "execution(* com.pingguo.spring5.aopanno.User.add(..))")
    public void afterThrowing() {
        System.out.println("AfterThrowing ... ...");
    }
    // 后置通知
    @After(value = "execution(* com.pingguo.spring5.aopanno.User.add(..))")
    public void after() {
        System.out.println("After ... ...");
    }

运行测试:

After ... ...
AfterThrowing ... ...
java.lang.ArithmeticException: / by zero

四、抽取相同切入点

在上述的介绍中,发现每个通知里的切入点表达式都是一样的,那么可以进行抽取。

修改增强类,使用 @Pointcut :

// 增强类
@Component
@Aspect
public class UserProxy {
    @Pointcut(value = "execution(* com.pingguo.spring5.aopanno.User.add(..))")
    public void pointDemo() {
    }
    // 前置通知
    @Before(value = "pointDemo()")
    public void before() {
        System.out.println("before ... ...");
    }
... ...

使用 @Pointcut 注解把表达式抽取出来到方法 pointDemo() 上,后续的通知里,value = "pointDemo()" 即可。

运行测试:

before ... ...
add ... ...
Process finished with exit code 0

如果需要改动表达式,只修改这一处就好。

五、多个增强类的优先级

如果有多个增强类对同一个方法进行增强,可以设置增强类的优先级。

给这 2 个增强类添加注解 @Order(1)、 @Order(2),注意,里面的数值越小,优先级越高。

新建的增强类 PersonProxy:

// 新建另一个增强类
@Component
@Aspect
@Order(1)
public class PersonProxy {
    @Pointcut(value = "execution(* com.pingguo.spring5.aopanno.User.add(..))")
    public void pointDemo() {
    }
    // 前置通知
    @Before(value = "pointDemo()")
    public void before() {
        System.out.println("PersonProxy 类的 before ... ...");
    }
}

之前的 增强类:

// 增强类
@Component
@Aspect
@Order(2)
public class UserProxy {
    @Pointcut(value = "execution(* com.pingguo.spring5.aopanno.User.add(..))")
    public void pointDemo() {
    }
    // 前置通知
    @Before(value = "pointDemo()")
    public void before() {
        System.out.println("before ... ...");
    }

运行测试:

PersonProxy 类的 before ... ...
before ... ...
add ... ...
Process finished with exit code 0

Order(1) 的增强了 PersonProxy 下的通知先执行。

以上就是Spring学习通过AspectJ注解方式实现AOP操作的详细内容,更多关于Spring注解AspectJ操作AOP的资料请关注我们其它相关文章!

(0)

相关推荐

  • Spring AOP底层原理及代理模式

    目录 Spring AOP底层原理代理模式 一.什么是 AOP 二.AOP 底层原理 1. 什么是代理? 2. 什么是静态代理 3. 什么是动态代理 Spring AOP底层原理代理模式 一.什么是 AOP AOP 就是面向切面编程,是 OOP(面向对象编程)的延续. 利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序可用性,同时也提高了开发效率. 通俗一点说,不用修改原代码,可以给原代码增加新的功能. 二.AOP 底层原理 AOP 底层原理是使用动

  • Spring AOP 创建代理对象详情

    目录 1 前言 2 创建代理对象 3 AOPContext Aop 上下文 4 AOP 分析汇总 5 JDK 动态代理和 CGLIB 的区别与联系 6 总结 1 前言 在这篇文章中中已经讲述了 AOP 的后置处理器和增强信息的获取,在本文中将继续分享 AOP 创建代理对象和上下文相关的内容. 2 创建代理对象 Spring AOP 使用 JDKProxy 和 CGLIB 两种方式来生成代理对象,具体使用哪一种需要根据 AopProxyFactory 接口的 createProxy 方法中的 Ad

  • 深入解析spring AOP原理及源码

    目录 @EnableAspectJAutoProxy 找切面 代理对象的创建 代理方法的执行 ExposeInvocationInterceptor#invoke 环绕通知的执行 前置通知的执行 后置通知的执行 返回后通知的执行 异常通知的执行 @EnableAspectJAutoProxy @EnableAspectJAutoProxy注解用于开启AOP功能,那么这个注解底层到底做了什么呢? 查看@EnableAspectJAutoProxy的源码,发现它使用@Import注解向Spring容

  • Spring AOP操作的相关术语及环境准备

    目录 一.常用术语 二.准备工作 1. 引入依赖 2. 切入点表达式 (1)示例1 (2)示例2 一.常用术语 在后续使用 AOP 中会用到几个专业术语:连接点.切入点.通知(增强).切面. 分别是什么意思? 来看这里有个 User 类,里面有增删改查 4 个方法. public class User { public void add() {} public void delete() {} public void update() {} public void select() {} } 以

  • 详解Java Spring AOP

    目录 前言 一.AOP底层原理 1.AOP底层使用动态代理 二.AOP术语 1.连接点 2.切入点 3.通知(增强) 4.切面 三.AOP 操作(准备工作) Spring 框架一般都是基于 AspectJ 实现 AOP 操作 方式一:使用Spring的接口实现增添功能 方式二:自定义类 方式三:全注解配置实现 总结 前言 面向切面编程,利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率.即不改变源代码而添加新功能,可插

  • Java的Spring AOP详细讲解

    目录 什么是AOP&作用 AOP的动态代理技术 基于JDK的动态代理 cglib动态代理 AOP相关概念 AOP开发明确事项 需要编写的内容 AOP技术实现的内容 AOP底层使用哪种代理方式 基于XML的AOP开发 切面表达式 通知类型 切点表达式抽取 基于注解的AOP开发 注解通知类型和切面表达式的抽取 类型 抽取表达式 总结 什么是AOP&作用 AOP 为 Aspect Oriented Programming 的缩写,意思为面向切面编程,是通过预编译方式和运行期动态代理实现程序功能的

  • Spring学习通过AspectJ注解方式实现AOP操作

    目录 Spring注解AspectJ操作AOP 一.被增强类 二.增强类 三.进行通知的配置 1. spring 配置文件中,开启扫描. 2. 使用注解创建 User 和 UserProxy 对象 3. 在增强类上使用注解 @Aspect 4. spring配置,开启生成代理对象 5. 配置不同类型的通知 四.抽取相同切入点 五.多个增强类的优先级 Spring注解AspectJ操作AOP 一.被增强类 新建一个被增强的类 User,下面有个 add() 方法. package com.ping

  • 使用Spring的注解方式实现AOP实例

    spring对AOP的实现提供了很好的支持.下面我们就使用Spring的注解来完成AOP做一个例子. 首先,为了使用Spring的AOP注解功能,必须导入如下几个包.aspectjrt.jar,aspectjweaver.jar,cglib-nodep.jar.然后我们写一个接口 package com.bird.service; public interface PersonServer { public void save(String name); public void update(S

  • 关于spring boot整合kafka+注解方式

    目录 spring boot自动配置方式整合 spring boot自动配置的不足 spring boot下手动配置kafka 批量消费消息 spring boot整合kafka报错 spring boot自动配置方式整合 spring boot具有许多自动化配置,对于kafka的自动化配置当然也包含在内,基于spring boot自动配置方式整合kafka,需要做以下步骤. 引入kafka的pom依赖包 <!-- https://mvnrepository.com/artifact/org.s

  • Spring使用AspectJ注解和XML配置实现AOP

    本文演示的是Spring中使用AspectJ注解和XML配置两种方式实现AOP 下面是使用AspectJ注解实现AOP的Java Project 首先是位于classpath下的applicationContext.xml文件 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmln

  • 详解Spring Aop实例之AspectJ注解配置

    上篇<Spring Aop实例之xml配置>中,讲解了xml配置方式,今天来说说AspectJ注解方式去配置spring aop. 依旧采用的jdk代理,接口和实现类代码请参考上篇博文.主要是将Aspect类分享一下: package com.tgb.aop; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Aft

  • spring AOP自定义注解方式实现日志管理的实例讲解

    今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在applicationContext-mvc.xml中要添加的 <mvc:annotation-driven /> <!-- 激活组件扫描功能,在包com.gcx及其子包下面自动扫描通过注解配置的组件 --> <context:component-scan base-package=&qu

  • aop注解方式实现全局日志管理方法

    1:日志实体类 public class SysLog { /** */ private Integer id; /** 日志描述*/ private String description; /** 执行的方法*/ private String method; /** 日志类型 0:操作日志:1:异常日志*/ private Integer logType; /** 客户端请求的ip地址*/ private String requestIp; /** 异常代码*/ private String

  • Spring中的AOP操作你了解吗

    目录 一.AOP操作术语 1. 连接点 2. 切入点 3. 通知(增强) 4. 切面 二.AOP操作 2.1 切入点表达式 2.2 AOP操作(AspectJ 注解方式) 2.3 相同切入点的抽取 2.4 多个增强类对同一个方法进行增强,设置增强类优先级 三.结束 一.AOP操作术语 1. 连接点 类里面哪些方法可以被增强,这些可以被增强的方法就称为连接点. 2. 切入点 实际被真正增强的方法,称为切入点. 3. 通知(增强) (1)实际增强的逻辑部分称为通知(增强) (2)通知有如下多种类型,

  • 详解Spring学习总结——Spring实现AOP的多种方式

    目录 一.基于XML配置的Spring AOP 二.使用注解配置AOP 三.AspectJ切点函数 四.AspectJ通知注解 五.零配置实现Spring IoC与AOP AOP(Aspect Oriented Programming)面向切面编程,通过预编译方式和运行期动态代理实现程序功能的横向多模块统一控制的一种技术.AOP是OOP的补充,是spring框架中的一个重要内容.利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发

  • Spring Aop之AspectJ注解配置实现日志管理的方法

    最近项目要做一个日志功能,我用Spring Aop的注解方式来实现. 创建日志注解 package com.wyj.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lan

随机推荐