Spring AOP系列--AOP+注解 实例
发布日期:2021-05-10 13:43:50 浏览次数:22 分类:精选文章

本文共 13868 字,大约阅读时间需要 46 分钟。

其他网址

另见《深入浅出Spring Boot 2.x》=> 4.3 AOP开发详解

简介

因为AOP可以将切点设为注解类,因此,若想控制Controller,只需要控制@RequestMapping,即:

@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")

创建工程

本文工程全部源码:

pom.xml

4.0.0
org.springframework.boot
spring-boot-starter-parent
2.3.1.RELEASE
com.example
demo_springaop-simple
0.0.1-SNAPSHOT
demo_springaop-simple
Demo project for Spring Boot
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-aop
org.springframework.boot
spring-boot-starter-test
test
org.projectlombok
lombok
1.16.20
provided
org.springframework.boot
spring-boot-maven-plugin

公共代码

注解类

package com.example.demo.annotation;import java.lang.annotation.*;@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @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 org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;@RequestMapping("/user")@Controllerpublic class UserController {    @Autowired    UserService userService;    @RequestMapping("/print")    @ResponseBody    public User testPrint(User user) {        userService.printUser(user);        return user;    }    @RequestMapping("/add")    @ResponseBody    @OperationLog(type = "添加", desc = "添加数据")    public User testAdd(User user) {        return user;    }    @RequestMapping("/update")    @ResponseBody    @OperationLog(type = "更新", desc = "更新数据")    public User testUpdate(User user) {        userService.printUser(user);        return user;    }}

Entity

package com.example.demo.entity;import lombok.Data;@Datapublic 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;@Servicepublic 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;@SpringBootApplicationpublic class DemoSpringaopSimpleApplication {    public static void main(String[] args) {        SpringApplication.run(DemoSpringaopSimpleApplication.class, args);    }}

单入参有返回值

package com.example.demo.aspect;import com.example.demo.annotation.OperationLog;import com.example.demo.entity.User;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.aspectj.lang.reflect.MethodSignature;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import java.lang.annotation.Annotation;import java.lang.reflect.Method;import java.text.SimpleDateFormat;@Aspect@Componentpublic class OperationLogAspect {    //切点表达式,表示加了OperationLog注解的都是切点,路径是自定义注解的全路径    @Pointcut("@annotation(com.example.demo.annotation.OperationLog)")    public void pointcut() {    }//    有ProceedingJoinPoint无注解类,有返回值    @Around("pointcut()")    public Object around1(ProceedingJoinPoint joinPoint) throws Throwable {        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();        Method method = methodSignature.getMethod();        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("-----------------------------------------------");        Object object = joinPoint.proceed();        OperationLog operationLog = method.getAnnotation(OperationLog.class);        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());            }        }        return object;    }}

测试

postman访问:

后端结果

joinPoint.getTarget().toString()  : com.example.demo.controller.UserController@10852612methodSignature.getName()         : testAddmethod.getName()                  : testAddmethod.getReturnType().getName()  : com.example.demo.entity.User-----------------------------------------------type: 添加	desc: 添加数据-----------------------------------------------User(id=321, userName=Tony, note=abc)id是:321; 名字是:Tony; 备注是:abc

postman结果

{    "id": 321,    "userName": "Tony",    "note": "abc"}

postman访问:

后端结果

joinPoint.getTarget().toString()  : com.example.demo.controller.UserController@10852612methodSignature.getName()         : testUpdatemethod.getName()                  : testUpdatemethod.getReturnType().getName()  : com.example.demo.entity.User-----------------------------------------------id = 321	 userName = Tony	 note = abctype: 更新	desc: 更新数据-----------------------------------------------User(id=321, userName=Tony, note=abc)id是:321; 名字是:Tony; 备注是:abc

postman结果

{    "id": 321,    "userName": "Tony",    "note": "abc"}

双参数有返回值

package com.example.demo.aspect;import com.example.demo.annotation.OperationLog;import com.example.demo.entity.User;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.aspectj.lang.reflect.MethodSignature;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import java.lang.annotation.Annotation;import java.lang.reflect.Method;import java.text.SimpleDateFormat;@Aspect@Componentpublic class OperationLogAspect {    //切点表达式,表示加了OperationLog注解的都是切点,路径是自定义注解的全路径    @Pointcut("@annotation(com.example.demo.annotation.OperationLog)")    public void pointcut() {    }//    有ProceedingJoinPoint和注解类,有返回值    @Around("@annotation(operationLog)")    public Object around2(ProceedingJoinPoint joinPoint, OperationLog operationLog) throws Throwable{        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();        Method method = methodSignature.getMethod();        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("-----------------------------------------------");        Object object = joinPoint.proceed();        System.out.println("method.getName(): " + method.getName());        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());            }        }        return object;    }}

测试

postman访问:

后端结果

joinPoint.getTarget().toString()  : com.example.demo.controller.UserController@36efe205methodSignature.getName()         : testAddmethod.getName()                  : testAddmethod.getReturnType().getName()  : com.example.demo.entity.User-----------------------------------------------method.getName(): testAddtype: 添加	desc: 添加数据-----------------------------------------------User(id=321, userName=Tony, note=abc)id是:321; 名字是:Tony; 备注是:abc

postman结果

{    "id": 321,    "userName": "Tony",    "note": "abc"}

postman访问:

后端结果

joinPoint.getTarget().toString()  : com.example.demo.controller.UserController@36efe205methodSignature.getName()         : testUpdatemethod.getName()                  : testUpdatemethod.getReturnType().getName()  : com.example.demo.entity.User-----------------------------------------------id = 321	 userName = Tony	 note = abcmethod.getName(): testUpdatetype: 更新	desc: 更新数据-----------------------------------------------User(id=321, userName=Tony, note=abc)id是:321; 名字是:Tony; 备注是:abc

postman结果

{    "id": 321,    "userName": "Tony",    "note": "abc"}

单入参无返回值

package com.example.demo.aspect;import com.example.demo.annotation.OperationLog;import com.example.demo.entity.User;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.aspectj.lang.reflect.MethodSignature;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import java.lang.annotation.Annotation;import java.lang.reflect.Method;import java.text.SimpleDateFormat;@Aspect@Componentpublic class OperationLogAspect {    //切点表达式,表示加了OperationLog注解的都是切点,路径是自定义注解的全路径    @Pointcut("@annotation(com.example.demo.annotation.OperationLog)")    public void pointcut() {    }//    有ProceedingJoinPoint无注解类,无返回值    @Around("pointcut()")    public void around3(ProceedingJoinPoint joinPoint) throws Throwable {        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();        Method method = methodSignature.getMethod();        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("-----------------------------------------------");        Object object = joinPoint.proceed();        OperationLog operationLog = method.getAnnotation(OperationLog.class);        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());            }        }    }}

测试

postman访问:

后端结果:

joinPoint.getTarget().toString()  : com.example.demo.controller.UserController@71e616a3methodSignature.getName()         : testAddmethod.getName()                  : testAddmethod.getReturnType().getName()  : com.example.demo.entity.User-----------------------------------------------type: 添加	desc: 添加数据-----------------------------------------------User(id=321, userName=Tony, note=abc)id是:321; 名字是:Tony; 备注是:abc

postman结果

postman访问:

后端结果:

joinPoint.getTarget().toString()  : com.example.demo.controller.UserController@71e616a3methodSignature.getName()         : testUpdatemethod.getName()                  : testUpdatemethod.getReturnType().getName()  : com.example.demo.entity.User-----------------------------------------------id = 321	 userName = Tony	 note = abctype: 更新	desc: 更新数据-----------------------------------------------User(id=321, userName=Tony, note=abc)id是:321; 名字是:Tony; 备注是:abc

postman结果

上一篇:Spring IOC--注入与装配
下一篇:SpringMVC--过滤器/拦截器

发表评论

最新留言

初次前来,多多关照!
[***.217.46.12]2025年04月07日 11时58分42秒