首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
SAAS
ToB门户
了解全球最新的ToB事件
论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
微博
Follow
记录
Doing
博客
Blog
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
排行榜
Ranklist
相册
Album
应用中心
qidao123.com ToB IT社区-企服评测·应用市场
»
论坛
›
大数据
›
数据仓库与分析
›
【Spring AOP】_利用注解编写AOP步伐
返回列表
发新帖
【Spring AOP】_利用注解编写AOP步伐
[复制链接]
发表于 2025-10-20 18:59:17
|
显示全部楼层
|
阅读模式
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要
登录
才可以下载或查看,没有账号?
立即注册
×
目次
1. 以增长方法实行时间为例利用AOP
1.1 引入AOP依赖
1.2 编写AOP步伐
2. AOP的紧张概念
3. AOP关照范例与关照方法标注
3.1 在关照方法前利用对应注解
3.2 利用@Pointcut注解提取公共切点表达式
3.3 跨类利用切点
3.4 切面类排序
1. 以增长方法实行时间为例利用AOP
1.1 引入AOP依赖
在pom.xml中增长关于AOP的设置:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
复制
代码
1.2 编写AOP步伐
以图书管理体系为例,为每个方法增长耗时盘算与
日志
打印。
创建aspect包,在其下创建TimeAspect类:
package com.example.bookmanagementsystem.aspect;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Slf4j
@Component
public class TimeAspect {
@Around("execution(* com.example.bookmanagementsystem.controller.*.*(..))")
public Object timeCost(ProceedingJoinPoint joinPoint) throws Throwable {
long start=System.currentTimeMillis();
// 执行目标方法
Object result=joinPoint.proceed();
long end=System.currentTimeMillis();
log.info(joinPoint+"消耗时间:"+(end-start)+"ms");
return result;
}
}
复制
代码
关于注解:
1、@Aspect:体现该类是一个切面类;
2、@Around:用于指明切面类的作用域与作用方式(在哪个环节,对哪些方法);
关于切面类成员方法:
1、timeCost方法的参数是一个ProceedingJoinPoint范例的对象,体现目的方法;
2、
代码
被分为三大部分:
2. AOP的紧张概念
1、切点:一组通过表达式形貌的规则;
2、毗连点:切面作用/形貌的方法,即被AOP控制的目的方法;
3、关照:详细要做处置处罚的逻辑;
4、切面:切点+关照即切面,一个类可以有多个切面;
以上述切面类为例:
3. AOP关照范例与关照方法标注
1、
@Around:围绕关照,此注解标注的关照方法在目的方法前、后都被实行
;
(最常用)
2、@Before:前置关照,此注解标注的关照方法在目的方法前被实行;
3、@After:
后置关照,此注解标注的关照方法在目的方法后被实行,无论是否发生非常都会实行;
4、
@AfterReturning
:
返回后关照,此注解标注的关照方法在目的方法后被实行,
有非常不会实行
;
5、
@AfterThrowing
:非常后关照,此注解标注的关照方法
在非常后被实行
;
3.1 在关照方法前利用对应注解
现在controller包下创建一个HelloController类,编写方法作为目的方法:
由于@AfterReturning与@AfterThrowing标注的方法在非常发生与否时返回差异,故编写两个方法使其满足一个正常运行,一个运行时报非常:
package com.zhouyou.demos.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@RequestMapping("/test1")
public String test1(){
return "hello";
}
@RequestMapping("/test2")
public int test2(){
return 10/0;
}
}
复制代码
在aspect包下创建TestAspect类,用于编写关照方法:
package com.zhouyou.demos.aspect;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Aspect
@Slf4j
@Component
public class AspectDemo {
@Around("execution(* com.zhouyou.demos.controller.*.*(..))")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
log.info("AspectDemo around 前");
Object result=joinPoint.proceed();
log.info("AspectDemo around 后");
return result;
}
@Before("execution(* com.zhouyou.demos.controller.*.*(..))")
public void doBefore(){
log.info("AspectDemo before");
}
@After("execution(* com.zhouyou.demos.controller.*.*(..))")
public void doAfter(){
log.info("AspectDemo after");
}
@AfterReturning("execution(* com.zhouyou.demos.controller.*.*(..))")
public void doAfterReturning(){
log.info("AspectDemo afterReturning");
}
@AfterThrowing("execution(* com.zhouyou.demos.controller.*.*(..))")
public void doAfterThrowing(){
log.info("AspectDemo afterThrowing");
}
}
复制代码
启动项目,依次根据路由映射访问test1方法和test2方法,可检察
日志
观察关照方法实行序次:
3.2 利用@Pointcut注解提取公共切点表达式
上述利用方法中,在利用对应注解标注关照方法时,须要重复编写公共切点表达式,这很不方便;
可利用@Pointcut提取公共切点表达式,在后续利用公共切点表达式时则直接利用@Pointcut标注的方法名即可;
修改3.1中的代码
package com.zhouyou.demos.aspect;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Aspect
@Slf4j
@Component
public class AspectDemo {
@Pointcut("execution(* com.zhouyou.demos.controller.*.*(..))")
private void pc(){
}
@Around("pc()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
log.info("AspectDemo around 前");
Object result=joinPoint.proceed();
log.info("AspectDemo around 后");
return result;
}
@Before("pc()")
public void doBefore(){
log.info("AspectDemo before");
}
@After("pc()")
public void doAfter(){
log.info("AspectDemo after");
}
@AfterReturning("pc()")
public void doAfterReturning(){
log.info("AspectDemo afterReturning");
}
@AfterThrowing("pc()")
public void doAfterThrowing(){
log.info("AspectDemo afterThrowing");
}
}
复制代码
3.3 跨类利用切点
现在aspect包中再创建一个切面类aspectDemo2,以@Before为例利用aspectDemo的切点。
package com.zhouyou.demos.aspect;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Slf4j
@Component
public class AspectDemo2 {
@Before("com.zhouyou.demos.aspect.AspectDemo.pc()")
public void doBefore(){
log.info("AspectDemo2 doBefore");
}
}
复制代码
启动项目,根据方法路由映射即可在
日志
处观察到关照方法的详细实行序次情况;
利用方法注意事项:
(1)在跨类利用公共切点时,须要利用全限定类名;
(2)在当前类中,若在其类中实现的切点须要在其他类中利用,则切点必须以public修饰。
利用private修饰的切点只能在当前类中利用;
3.4 切面类排序
现aspect包下由AspectDemo、AspectDemo1、AspectDemo2三个切面类,并在每个切面类中实现@Before关照和@After关照。
创建目的方法并指定路由映射,并举行访问,检察日志输出:
在接纳
默认排序的情况下
,默认接纳按照切面类的类名字母排序:
对于@Before关照,排名越靠前的先实行;
对于@After关照,排名越靠后的先实行;
但这并未便于管理,
Spring提供了@Order注解,用于给切面类设置优先级
:
对于@Before关照,@Order中的数字越小越先实行;
对于@After关照,@Order中的数字越大越先实行;
现对AspectDemo切面类利用Order(3)、AspectDemo1切面类利用Order(2)、AspectDemo2切面类利用Order(1),启动步伐检察日志输出:
回复
使用道具
举报
返回列表
浏览过的版块
DevOps与敏捷开发
Java
程序人生
移动端开发
鸿蒙
农民
+ 我要发帖
登录后关闭弹窗
登录参与点评抽奖 加入IT实名职场社区
去登录
微信订阅号
微信服务号
微信客服(加群)
H5
小程序
快速回复
返回顶部
返回列表