所有分类
  • 所有分类
  • 未分类

Spring之AOP–将方法上的注解做为切点(用@Before)

简介

说明

本文介绍Spring(SpringBoot)的AOP的用法:自定义注解,在Controller的方法上使用此注解,然后在AOP中获得注解和方法的相关信息。

本文使用@Before。

测试

访问测试页面:http://localhost:8080/doc.html

测试1:添加

后端结果

------------------ 方法信息 ------------------
joinPoint.getTarget().toString()  : com.example.demo.controller.UserController@4671b282
methodSignature.getName()         : testAdd
method.getName()                  : testAdd
method.getReturnType().getName()  : com.example.demo.entity.User
------------------ 注解数据 ------------------
type: 添加	desc: 添加数据
------------------ 入参数据 ------------------
User(id=123, userName=Tony, note=abc)
id是:123; 名字是:Tony; 备注是:abc
#################################################

测试2:更新

后端结果

------------------ 方法信息 ------------------
joinPoint.getTarget().toString()  : com.example.demo.controller.UserController@4671b282
methodSignature.getName()         : testUpdate
method.getName()                  : testUpdate
method.getReturnType().getName()  : com.example.demo.entity.User
------------------ 注解数据 ------------------
type: 更新	desc: 更新数据
------------------ 入参数据 ------------------
User(id=1, userName=Pepper, note=2)
id是:1; 名字是:Pepper; 备注是:2
#################################################
id = 1	 userName = Pepper	 note = 2

代码

创建工程

自定义注解类

package com.example.demo.annotation;

import java.lang.annotation.*;

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperationLog {
    //操作的类型,添加,更新,删除
    String type() default "add";

    //操作描述
    String desc() default "";
}

业务代码

Controller

package com.example.demo.controller;

import com.example.demo.annotation.OperationLog;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Api(tags = "用户")
@RequestMapping("/user")
@RestController
public class UserController {
    @Autowired
    private UserService userService;

    @ApiOperation("打印数据")
    @GetMapping("print")
    public User testPrint(User user) {
        userService.printUser(user);
        return user;
    }

    @ApiOperation("添加数据")
    @PostMapping("add")
    @OperationLog(type = "添加", desc = "添加数据")
    public User testAdd(User user) {
        return user;
    }

    @ApiOperation("更新数据")
    @PostMapping("update")
    @OperationLog(type = "更新", desc = "更新数据")
    public User testUpdate(User user) {
        userService.printUser(user);
        return user;
    }
}

Entity

package com.example.demo.entity;

import lombok.Data;

@Data
public class User {
    private Integer id;

    private String userName;

    private String note;
}

Service

package com.example.demo.service;

import com.example.demo.entity.User;

public interface UserService {
    public void printUser(User user);
}
package com.example.demo.service.impl;

import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {
    @Override
    public void printUser(User user) {
        if (user == null) {
            throw new RuntimeException("检查用户参数是否为空");
        }
        System.out.print("id = " + user.getId());
        System.out.print("\t userName = " + user.getUserName());
        System.out.println("\t note = " + user.getNote());
    }
}

启动类

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoSpringaopSimpleApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoSpringaopSimpleApplication.class, args);
    }
}

AOP(核心)

@Around入参为ProceedingJoinPoint + 注解类,有返回值。这样就不用写@PointCut了,返回值会作为Controller数据返回回去。

package com.example.demo.aspect;

import com.example.demo.annotation.OperationLog;
import com.example.demo.entity.User;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * Before结合方法的注解获得操作日志
 */
@Aspect
@Component
public class OperationLogAspectByBefore {

    //有ProceedingJoinPoint无注解类,有返回值
    @Before("@annotation(operationLog)")
    public void before(JoinPoint joinPoint, OperationLog operationLog) throws Throwable {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        System.out.println("------------------ 方法信息 ------------------");
        System.out.println("joinPoint.getTarget().toString()  : " + joinPoint.getTarget().toString());
        System.out.println("methodSignature.getName()         : " + methodSignature.getName());
        System.out.println("method.getName()                  : " + method.getName());
        System.out.println("method.getReturnType().getName()  : " + method.getReturnType().getName());

        System.out.println("------------------ 注解数据 ------------------");
        System.out.print("type: " + operationLog.type());
        System.out.println("\tdesc: " + operationLog.desc());

        System.out.println("------------------ 入参数据 ------------------");
        Object[] objects = joinPoint.getArgs();
        for (Object o : objects) {
            System.out.println(o);
            if (o instanceof User) {
                System.out.println("id是:" + ((User) (o)).getId() +
                        "; 名字是:" + ((User) (o)).getUserName() +
                        "; 备注是:" + ((User) (o)).getNote());
            }
        }
        System.out.println("#################################################");
    }
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo_SpringAOP</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo_SpringAOP</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
            <version>3.0.3</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
            <scope>provided</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
0

评论0

请先

显示验证码
没有账号?注册  忘记密码?

社交账号快速登录