public class User {
private Integer id;
private String username;
private String note; public User(Integer id, String username, String note) {
this.id = id;
this.username = username;
this.note = note;
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getNote() {
return note;
} public void setNote(String note) {
this.note = note;
} @Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", note='" + note + '\'' +
'}';
}
}

接口:

//@Component接口不用添加注入到容器,因为接口不能进行实例化
public interface UserService {
public void printUser(User user);
public void manyAspect();
}

实现类:

@Component
public class UserServiceImpl implements UserService { /**
* 这个方法将作为我们的AOP的接入点
* @param user
*/
@Override
public void printUser(User user) {
if (user.getUsername() == null){
throw new RuntimeException("检查用户参数是否为空。。。。");
}
System.out.println("id = "+ user.getId());
System.out.println("username = " + user.getUsername());
System.out.println("note = " + user.getNote());
} @Override
public void manyAspect() {
System.out.println("manyAspect------");
}
}
/**
* 定义切面
* @Aspect声明切面
*/
//@Aspect
public class MyAspect { //避免我们重复写一个表达式,引入了切入点概念PointCut,描述哪些类的哪些方法需要开启AOP编程。
@Pointcut("execution(* quan.springframework.springbootaop.aopdone.UserServiceImpl.printUser(..))")
public void pointCut(){
} @Before("pointCut()")
public void before(){
System.out.println("before......");
} @After("pointCut()")
public void after(){
System.out.println("after......");
} @AfterReturning("pointCut()")
public void afterreturning(){
System.out.println("agterreturning.....");
} @AfterThrowing("pointCut()")
public void afterthrowing(){
System.out.println("afterthrowing.....");
} /**
* ProceedingJoinPoint类型参数,给参数的对象中有个方法proceed方法。回调原来的方法。
* @Around注解会取代原有目标的方法的通知。不进行回调得时候,方法是空的。
* @param joinPoint
* @throws Throwable
*/
@Around("pointCut()")
public void around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("around before....");
//可以在这里打断点去查看joinPoint的内容
joinPoint.proceed();
System.out.println("around after....");
}
/**
* http://localhost:8080/aop/userprint?id=22&username=quan&note=huolala
* 有回调:
* around before...
* before......
* id = 22
* username = quan
* note = huolala
* agterreturning.....
* after......
* around after....
* ################
* 没回调:
* around before....
* around after....
*/ /**
* @DeclareParents作用:引入新的类来增强服务,
* value:指向你要增强功能的目标对象,这里要增强对象为UserServiceImpl对象
* defaultImpl:引入增强功能的类,UserValidatorImpl提供校验用户是否为空的
*/
@DeclareParents(value = "quan.springframework.springbootaop.aopdone.UserServiceImpl",defaultImpl = UserValidatorImpl.class)
public UserValidator userValidator; @DeclareParents(value = "quan.springframework.springbootaop.aopdone.UserServiceImpl",defaultImpl = UserValidatorIdImpl.class)
public UserValidatorId userValidatorId; /**
* 通知获取参数,
* && args(user)并将目标对象方法-名称为user的参数传递进来。
* @param joinPoint
* @param user
* 注意:
* JoinPoint类型的参数对于非环绕通知而言的参数。spring AOP自动传递到通知中
* 环绕通知自动你传递的参数为ProceedingJoinPoint类型的参数。
*/
@Before("pointCut() && args(user)")
public void beforeParam(JoinPoint joinPoint,User user){
Object[] args = joinPoint.getArgs();
System.out.println(args);
System.out.println("before param....");
} // @Before("execution(* quan.springframework.springbootaop.aopdone.UserServiceImpl.printUser(..))")
// public void before(){
// System.out.println("before......");
// }
//
// @After("execution(* quan.springframework.springbootaop.aopdone.UserServiceImpl.printUser(..))")
// public void after(){
// System.out.println("after......");
// }
//
// @AfterReturning("execution(* quan.springframework.springbootaop.aopdone.UserServiceImpl.printUser(..))")
// public void afterreturning(){
// System.out.println("agterreturning.....");
// }
//
// @AfterThrowing("execution(* quan.springframework.springbootaop.aopdone.UserServiceImpl.printUser(..))")
// public void afterthrowing(){
// System.out.println("afterthrowing.....");
// } /**
* execution(* quan.springframework.springbootaop.aopdone.UserServiceImpl.printUser(..))
* execution:表示执行时,拦截里面的正则匹配方法;
* *:表示任意返回类型的方法
* quan.springframework.springbootaop.aopdone.UserServiceImpl:指定目标对象的全限定类名
* printUser:指定目标对象的方法
* (**):表示任意参数进行匹配
*/ }

多切面:

/**
* 第一个切面
*/
@Order(3)
@Aspect
public class MyManyAop { @Pointcut("execution(* quan.springframework.springbootaop.aopdone.UserServiceImpl.manyAspect(..))")
public void manyAspects(){
} @Before("manyAspects()")
public void before(){
System.out.println("MymanyAop1---before......");
} @After("manyAspects()")
public void after(){
System.out.println("MymanyAop1---after......");
} @AfterReturning("manyAspects()")
public void afterreturning(){
System.out.println("MymanyAop1---agterreturning.....");
} }
/**
* 第二个切面
*/
@Order(2)
@Aspect
public class MyManyAop2 { @Pointcut("execution(* quan.springframework.springbootaop.aopdone.UserServiceImpl.manyAspect(..))")
public void manyAspects(){
} @Before("manyAspects()")
public void before(){
System.out.println("MymanyAop2---before......");
} @After("manyAspects()")
public void after(){
System.out.println("MymanyAop2---after......");
} @AfterReturning("manyAspects()")
public void afterreturning(){
System.out.println("MymanyAop2---agterreturning.....");
}
}
/**
* 第三个切面
*/
@Order(1)
@Aspect
public class MyManyAop3 { @Pointcut("execution(* quan.springframework.springbootaop.aopdone.UserServiceImpl.manyAspect(..))")
public void manyAspects(){
} @Before("manyAspects()")
public void before(){
System.out.println("MymanyAop3---before......");
} @After("manyAspects()")
public void after(){
System.out.println("MymanyAop3---after......");
} @AfterReturning("manyAspects()")
public void afterreturning(){
System.out.println("MymanyAop3---agterreturning.....");
}
}

各个切面需要加入到容器当中:

@Configuration
public class AopConfiguration { /**
* 需要将切面加入到容器当中才能被织入
* @return
*/
@Bean("myAspect")
public MyAspect initMyAspect(){
return new MyAspect();
} /**
* 第一个切面
*/
@Bean("myManyAop")
public MyManyAop initMyManyAspect1(){
return new MyManyAop();
} /**
* 第二个切面
*/
@Bean("myManyAop2")
public MyManyAop2 initMyManyAspect2(){
return new MyManyAop2();
} /**
* 第三个切面
*/
@Bean("myManyAop3")
public MyManyAop3 initMyManyAspect3(){
return new MyManyAop3();
} }

通过类增强的:

/**
* 新建一个增强接口
*/
public interface UserValidator { public boolean validate(User user);
} /**
* 增强接口实现类
*/
public class UserValidatorImpl implements UserValidator { @Override
public boolean validate(User user) {
System.out.println("add validate");
return user.getUsername() != null;
}
}
public interface UserValidatorId {
public boolean idBigTWY(User user);
} public class UserValidatorIdImpl implements UserValidatorId{ @Override
public boolean idBigTWY(User user) {
System.out.println("UserValidatorId");
return user.getId() > 20;
}
}

什么是织入:

/**
* 织入:生成动态代理对象并且将切面和目标对象方法编织称为约定流程的过程
* Spring推荐的方式是接口+实现类的模式。
* spring支持JDK和CGLIB;
* JDK要求被代理对象必须拥有接口。
* CGLIB不做要求
* spring处理规则:当需要使用AOP的类拥有接口时,会以JDK动态代理运行,否则已CGLIB运行
* 注意:
* Spring 5.x 中 AOP 默认依旧使用 JDK 动态代理。
* SpringBoot 2.x 开始,为了解决使用 JDK 动态代理可能导致的类型转化异常而默认使用 CGLIB。
*/
@Controller
@RequestMapping("/aop")
public class AopController { @Autowired
UserService userService; @RequestMapping("/userprint")
@ResponseBody
public User pringUser(Integer id,String username,String note){
User user = new User(id,username,note);
userService.printUser(user);
return user;
}
/**
* request:
*http://localhost:8080/aop/userprint?id=22&username=quan&note=huolala
* result:
* before......
* id = 22
* username = quan
* note = huolala
* agterreturning.....
* after......
*/ @RequestMapping("/quote")
@ResponseBody
public User validateAndPrint(int id,String username,String note){
User user = new User(id,username,note);
//强制转换为UserValidator。
UserValidator userValidator = (UserValidator)userService;
if ( userValidator.validate(user) ){//判断是否为空user.username是否为空
userService.printUser(user);
} UserValidatorId userValidatorId = (UserValidatorId)userService;
if (userValidatorId.idBigTWY(user)){
System.out.println(user.getId());
}
return user;
} @RequestMapping("/many")
@ResponseBody
public String many(){
userService.manyAspect();
return "many aspect";
}
/**
* 顺序不一样的。
* MymanyAop1---before......
* MymanyAop2---before......
* MymanyAop3---before......
* manyAspect------
* MymanyAop3---agterreturning.....
* MymanyAop3---after......
* MymanyAop2---agterreturning.....
* MymanyAop2---after......
* MymanyAop1---agterreturning.....
* MymanyAop1---after......
*/ /**
* 加入Order:
* MymanyAop3---before......
* MymanyAop2---before......
* MymanyAop1---before......
* manyAspect------
* MymanyAop1---agterreturning.....
* MymanyAop1---after......
* MymanyAop2---agterreturning.....
* MymanyAop2---after......
* MymanyAop3---agterreturning.....
* MymanyAop3---after......
* 前置通知before都是从小到大运行,而后置通知和返回通知都是从大到小运行
* 典型的责任链模式顺序。
*/
}

spring-boot中的AOP的更多相关文章

  1. Spring Boot中使用AOP统一处理Web请求日志

    AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是Spring框架中的一个重要内容,它通 ...

  2. Spring Boot中使用AOP记录请求日志

    这周看别人写的springboot后端代码中有使用AOP记录请求日志,以前没接触过,因此学习下. 一.AOP简介 AOP为Aspect Oriented Programming的缩写,意为:面向切面编 ...

  3. 46. Spring Boot中使用AOP统一处理Web请求日志

    在之前一系列的文章中都是提供了全部的代码,在之后的文章中就提供核心的代码进行讲解.有什么问题大家可以给我留言或者加我QQ,进行咨询. AOP为Aspect Oriented Programming的缩 ...

  4. 转:Spring Boot中使用AOP统一处理Web请求日志

    在spring boot中,简单几步,使用spring AOP实现一个拦截器: 1.引入依赖: <dependency> <groupId>org.springframewor ...

  5. Spring boot中使用aop详解

      版权声明:本文为博主武伟峰原创文章,转载请注明地址http://blog.csdn.net/tianyaleixiaowu.       aop是spring的两大功能模块之一,功能非常强大,为解 ...

  6. (转)Spring Boot中使用AOP统一处理Web请求日志

    AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是Spring框架中的一个重要内容,它通 ...

  7. Spring Boot中自定义注解+AOP实现主备库切换

    摘要: 本篇文章的场景是做调度中心和监控中心时的需求,后端使用TDDL实现分表分库,需求:实现关键业务的查询监控,当用Mybatis查询数据时需要从主库切换到备库或者直接连到备库上查询,从而减小主库的 ...

  8. 56. spring boot中使用@Async实现异步调用【从零开始学Spring Boot】

    什么是"异步调用"? "异步调用"对应的是"同步调用",同步调用指程序按照定义顺序依次执行,每一行程序都必须等待上一行程序执行完成之后才能执 ...

  9. 如何优雅地在 Spring Boot 中使用自定义注解,AOP 切面统一打印出入参日志 | 修订版

    欢迎关注个人微信公众号: 小哈学Java, 文末分享阿里 P8 资深架构师吐血总结的 <Java 核心知识整理&面试.pdf>资源链接!! 个人网站: https://www.ex ...

  10. Spring AOP动态代理实现,解决Spring Boot中无法正常启用JDK动态代理的问题

    Spring AOP底层的动态代理实现有两种方式:一种是JDK动态代理,另一种是CGLib动态代理. JDK动态代理 JDK 1.3版本以后提供了动态代理,允许开发者在运行期创建接口的代理实例,而且只 ...

随机推荐

  1. [LeetCode]1281. 整数的各位积和之差

    给你一个整数 n,请你帮忙计算并返回该整数「各位数字之积」与「各位数字之和」的差. 示例 1: 输入:n = 234 输出:15 解释: 各位数之积 = 2 * 3 * 4 = 24 各位数之和 = ...

  2. 基于C#打造的OPCUA客户端应用

    OPC UA (Unified Architecture),是工业4.0的标准通信规范,大家现在都不陌生. 目前大部分工控行业的应用系统都逐渐的在向OPC UA靠拢,所以随着iot的发展,OPC UA ...

  3. react中配置路由

    一个路由就是一个通道,页面之间的跳转其实就是路由的切换,所以每个应用的路由配置是必须的,浅谈react中怎么配置路由 首先你要在src文件夹下新建一个router的文件下,在router文件下新建一个 ...

  4. CobaltStrike逆向学习系列(14):CS功能分析-DotNet

    这是[信安成长计划]的第 14 篇文章 0x00 目录 0x01 DotNet功能分析 0x02 DotNet功能执行 0x03 写在最后 在上两篇文章中,讲述了 CS 中的一种功能执行方式 RDI, ...

  5. NSSCTF-[鹤城杯 2021]A_MISC

    下载压缩包,解压需要输入密码,使用winhex打开发现不是zip的伪加密,然后使用爆破工具进行爆破得到密码 解压压缩包获得一个png打开是一个URL,常用的都知道,百度网盘的文件分享的链接,复制打开U ...

  6. 利用AWVS扫描Web漏洞

    实验目的 利用AWVS扫描Web漏洞. 实验原理 AWVS是一款知名的网络漏洞扫描工具,它通过网络爬虫测试你的网站安全,检测流行安全漏洞. 实验内容 AWVS是一个自动化的web应用程序安全测试工具, ...

  7. [MethodImpl(MethodImplOptions.Synchronized)]与lock机制

    [MethodImpl(MethodImplOptions.Synchronized)]与lock机制 在进行.NET开发时,经常会遇见如何保持线程同步的情况.在众多的线程同步的可选方式中,加锁无疑是 ...

  8. Python回顾笔记(此讲大致说明,详情请看之前的笔记)

    内容概要 数据分析(numpy,pandas,matplib) 数据清洗 爬虫 teableau软件 今日内容概要 Python知识回顾 数据分析 ipython模块 anaconda软件 numpy ...

  9. .Net/C#分库分表高性能O(1)瀑布流分页

    .Net/C#分库分表高性能O(1)瀑布流分页 框架介绍 依照惯例首先介绍本期主角:ShardingCore 一款ef-core下高性能.轻量级针对分表分库读写分离的解决方案,具有零依赖.零学习成本. ...

  10. LeetCode-016-最接近的三数之和

    最接近的三数之和 题目描述:给定一个包括 n 个整数的数组 nums 和 一个目标值 target.找出 nums 中的三个整数,使得它们的和与 target 最接近.返回这三个数的和.假定每组输入只 ...