
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; 备注是:abcpostman结果
{ "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; 备注是:abcpostman结果
{ "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; 备注是:abcpostman结果
{ "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; 备注是:abcpostman结果
{ "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; 备注是:abcpostman结果
无
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; 备注是:abcpostman结果
无
发表评论
最新留言
初次前来,多多关照!
[***.217.46.12]2025年04月07日 11时58分42秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
解决数据库报ORA-02289:序列不存在错误
2021-05-10
java实体类为什么要写.toString()方法?
2021-05-10
LINUX学习—FTP云服务器
2021-05-10
JS获取当前日期
2021-05-10
JavaScript数据类型
2021-05-11
js实现链表
2021-05-11
Vue项目中axios请求的时候使用localStorage去拼接报的401错误
2021-05-11
ArchLinux安装的各种问题(找不到磁盘、闪屏、键盘失效、声卡、网络、时间不同步)
2021-05-11
Vue中的动画封装(5-7)
2021-05-11
idea如何原始导入jar包
2021-05-11
归并排序模板
2021-05-11
IDEA配置mapper.xml模板
2021-05-11
OpenGL库的配置
2021-05-11
一文了解MXC抹茶交易所币本位合约交易
2021-05-11
MXC抹茶科普:以太坊链上的gas是什么?
2021-05-11
(ಥ_ಥ) VMware中安装Centos
2021-05-11
2021-04-07
2021-05-11
**精准实时采集数据是什么???
2021-05-11
计算机软考难不难?
2021-05-11