java Web-Spring AOP

AOP的概念

AOP:面向切面编程,面向方法编程。简单理解就是对特定方法的扩充的思想

例如我们要在特定方法进行方法的执行时间判断,我们假如去使用在每个方法去进行业务逻辑扩充,这样就太繁琐了,而使用AOP就可以简化操作。Spring AOP 底层是通过动态代理技术实现的,要想查看动态代理可以查看我之前的文章 动态代理技术

AOP 的组成

切面

AOP 是面向 切面编程,所以这是 AOP 最重要的功能。定义 AOP 是针对哪个统一的功能,这个功能就叫做一个切面。比如用户登录功能或方法的统计日志,他们就各自是一个切面。切面是由 切点 和 通知组成的。

连接点
就是所有可能触发 AOP(拦截方法的点),就称为连接点。

切点
切点会提供一个规则,用来匹配连接点,并且来实现通知。也就是在何处执行通知。

通知
重复的共性功能就是通知。就是规定 AOP 执行的时机和执行的方法,就是切点处的执行动作通知注解如下:

前置通知: 使用 @Before,通知方法会在目标方法调用之前执行。
后置通知: 使用 @After,通知方法会在目标方法返回或者抛出异常后调用。
返回之后通知: 使用 @AfterReturning,通知方法会在目标方法返回后调用。有异常不调用
抛异常后通知: 使用 @AfterThrowing,通知方法会在目标方法抛出异常后调用。
环绕通知: 使用 @Around通知包裹了被通知的方法,在被通知的方法通知之前和调用之后,执行自定义的行为。注意:1.AOP方法内需要调用procedingJoinPoint.proceed();方法来执行原始方法。2.Around环绕通知的返回值必须指定为Object来接收原始方法返回值

使用步骤

1.导入AOP依赖

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

2.编写AOP程序 

1.定义模板方法类,加上注解@Component交给IOC容器管理,还要加上@Aspect注解声明这是一个AOP类。

2.声明切点并定义通知:使用@PointCut注解注解一个方法来声明切点,也可以直接把表达式放入通知注解的参数中接收来声明切点

//方式一
@pointcut("切入点表达式)")
private void pt(){}//声明切点

@Before("pt()")
public void beforeTest(){
loog.info("beforeTest");
}
//方式二

@Before("切入点表达式")
public void beforeTest(){
loog.info("beforeTest");
}

 通知的执行顺序

当有多个切面的切入点都匹配到了目标方法时,多个通知方法都会被执行。

默认情况下顺序和切面类的类名大小有关,before通知类名靠前的 先执行,after通知类名靠前的 后执行。

我们可以通过@Order(数字)注解加在AOP类上来指定切面类控制顺序,before通知类数字小的 先执行,after通知数字小的 后执行。

切入点表达式

1.execution(...)

根据方法的返回值,包名,类名,方法名,方法参数等信息来匹配

语法:

execution([访问修饰符] 返回值 [包名.(类名./接口名.)]方法名(方法参数,要填全类名) [throws 异常])

可以使用通配符描述切入点:

*: 单个独立的任意符号,可以通配任意返回值、包名、类名、方法名、任意类型的一个参数,也可以通配包、类、方法名的一部分

案例:

execution(* com .*. service .*. update*(*))

.. : 多个连续的任意符号,可以通配任意层级的包,或任意类型、任意个数的参数

案例:

execution(* com.test .. DeptService .* ( .. ))

想要同时匹配多个连接点,可以使用||来连接

execution(* com.test.service. DeptService.list ()) || execution(* com.test.service. DeptService.delete (java. lang. Integer) ) 

2.@annotation(...)

根据标识注解进行匹配

语法:

@annotation(注解的全类名)

1.首先自定义一个注解用来标记匹配方法

@Retention(RetentionPolicy.RUNTIME)//元注解,运行时有效
@Target(ElementType.METHOD)//元注解,注解属性为方法上
public @intetface Mytest{}

2.在要切入的方法上加上注解

@MyTest
@Override
public List<dept> list{
List<dept> deptList =deptMapper.list();
return deptList;
}

@MyTest
@Override
public List<dept> delete{
deptMapper.delete(id);
}

3.使用切入点表达式

连接点

在Spring中用JoinPoint抽象了连接点,用它可以获得方法执行时的相关信息,如目标类名、方法名、方法参数等。我们可以在形参中声明参数来获取到他的对象。

  • 对于@Around 通知,获取连接点信息只能使用 ProceedingJoinPoint
  • 对于其他四种通知,获取连接点信息只能使用JoinPoint,它是 ProceedingJoinPoint 的父类型
@Around("execution(...)")

public Object around(ProceedingJoinPoint joinPoint) throws Throwable {

String className= joinPoint.getTarget().getClass().getName();//获取目标类名

Signature signature = joinPoint.getSignature();//获取目标方法签名

String methodName= joinPoint.getSignature().getName();//获取目标方法名

Object[] args= joinPoint.getArgs();//获取目标方法运行参数

Object res =joinPoint.proceed();//执行原始方法,获取返回值(环绕通知)

return res;

}
@Before("execution(...)")

public void before(JoinPoint joinPoint) {

String className = joinPoint.getTarget().getClass().getName();//获取目标类名

Signature signature= joinPoint.getSignature();//获取目标方法签名

String methodName=joinPoint.getSignature().getName();//获取目标方法名

Object[] args=joinPoint.getArgs();//获取目标方法运行参数

}

  • 8
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值