代码优雅的转变:基于注解的AOP编程在Spring中的实践

简介: 代码优雅的转变:基于注解的AOP编程在Spring中的实践


定义切面类

package world.xuewei.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
/**
 * 自定义切面类
 *
 * @author 薛伟
 * @since 2023/10/23 9:45
 */
@Aspect
public class MyAspect {
    /**
     * 定义切入点方法,方法体内编写额外功能
     * 注解 @Around:用于定义切入点,编写切入点表达式
     */
    @Around(value = "execution(* *(..))")
    public Object around(ProceedingJoinPoint joinPoint) {
        // 在此处编写前置操作
        System.out.println("Before");
        Object result = null;
        try {
            result = joinPoint.proceed();
        } catch (Throwable e) {
            // 在此处编写异常操作
            System.out.println("Exception");
        }
        // 在此处编写后置操作
        System.out.println("After");
        // 可以在此处编写新的返回值并返回
        return result;
    }
}

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: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 https://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- 开启 AOP 注解驱动开发 -->
    <aop:aspectj-autoproxy/>
    <!-- 注册原始对象 -->
    <bean id="userService" class="world.xuewei.proxy.UserServiceImpl"/>
    <!-- 注册自定义切面类 -->
    <bean id="around" class="world.xuewei.aspect.MyAspect"/>
</beans>

切入点复用

package world.xuewei.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
/**
 * 自定义切面类
 *
 * @author 薛伟
 * @since 2023/10/23 9:45
 */
@Aspect
public class MyAspect {
    /**
     * 单独定义切入点,只需要关注注解
     */
    @Pointcut("execution(* *(..))")
    public void p1() {
    }
    /**
     * 定义切入点方法,方法体内编写额外功能
     * 注解 @Around:用于定义切入点,编写切入点表达式
     */
    @Around(value = "p1()")
    public Object around(ProceedingJoinPoint joinPoint) {
        // 在此处编写前置操作
        System.out.println("Before");
        Object result = null;
        try {
            result = joinPoint.proceed();
        } catch (Throwable e) {
            // 在此处编写异常操作
            System.out.println("Exception");
        }
        // 在此处编写后置操作
        System.out.println("After");
        // 可以在此处编写新的返回值并返回
        return result;
    }
    @Around(value = "p1()")
    public Object around1(ProceedingJoinPoint joinPoint) {
        // 在此处编写前置操作
        System.out.println("Before");
        Object result = null;
        try {
            result = joinPoint.proceed();
        } catch (Throwable e) {
            // 在此处编写异常操作
            System.out.println("Exception");
        }
        // 在此处编写后置操作
        System.out.println("After");
        // 可以在此处编写新的返回值并返回
        return result;
    }
}

强制使用 Cglib 动态代理

<aop:aspectj-autoproxy proxy-target-class="true"/>

坑:代理方法调用

在同一个业务类中,进行业务方法间的调用时,只有最外层的方法才是通过代理对象调用的(加入了额外功能),内部调用的本类的其他方法都是通过原始对象调用,如果想要让内部的方法也通过代理对象调用,那么就需要实现 ApplicationContextAware 接口。

package world.xuewei.proxy;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
 * 用户服务实现
 *
 * @author 薛伟
 * @since 2023/10/18 17:49
 */
public class UserServiceImpl implements UserService, ApplicationContextAware {
    private ApplicationContext context;
    @Override
    public void register() {
        System.out.println("UserServiceImpl.register");
        UserService p = context.getBean(、"userService", UserService.class);
        p.login();
    }
    @Override
    public void login() {
        System.out.println("UserServiceImpl.login");
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
    }
}



相关文章
|
4天前
|
前端开发 Java 关系型数据库
使用IDEA搭建一个Spring + AOP (权限管理 ) + Spring MVC
使用IDEA搭建一个Spring + AOP (权限管理 ) + Spring MVC
|
4天前
|
Java
Springboot 使用自定义注解结合AOP方式校验接口参数
Springboot 使用自定义注解结合AOP方式校验接口参数
Springboot 使用自定义注解结合AOP方式校验接口参数
|
6天前
|
JSON 前端开发 Java
【JavaEE】Spring全家桶实现AOP-统一处理
【JavaEE】Spring全家桶实现AOP-统一处理
6 0
|
6天前
|
前端开发 Java 开发者
【JavaEE】面向切面编程AOP是什么-Spring AOP框架的基本使用
【JavaEE】面向切面编程AOP是什么-Spring AOP框架的基本使用
12 0
|
6天前
|
存储 缓存 Java
【JavaEE】Spring中注解的方式去获取Bean对象
【JavaEE】Spring中注解的方式去获取Bean对象
3 0
|
6天前
|
Java 数据库连接 应用服务中间件
Spring5源码(39)-Aop事物管理简介及编程式事物实现
Spring5源码(39)-Aop事物管理简介及编程式事物实现
27 0
|
6天前
AOP&面向切面编程
AOP&面向切面编程
58 0
|
6天前
|
Java 程序员 Maven
Spring AOP入门指南:轻松掌握面向切面编程的基础知识
Spring AOP入门指南:轻松掌握面向切面编程的基础知识
|
6天前
|
数据库
AOP(面向切面编程)的基本概念和原理
AOP(面向切面编程)的基本概念和原理
99 0
|
6月前
|
缓存 监控 Java
Spring框架之AOP(面向切面编程)
Spring框架之AOP(面向切面编程)
34 0