Spring之Spring Aop

AOP的简介

Aop 是面向切面编程,AOP的的核心是切面。AOP在不修改源代码本身的前提下使用运行时的动态代理技术对已有的代码逻辑增强。AOP可以实现组件化,可拔插式的功能扩展,通过简单配置即可将功能增强到指定的切入点。可用于权限认证、日志、事务处理。

AOP的底层原理

Aop的底层是由运行时动态代理支撑,在bean初始化流程中,借助BeanPostProcessor(后置处理器)将原始目标对象织入通知,生成代理对象,AOP设计原理是对原有的业务逻辑进行横切增强,使用不同的通知织入方式,她有不同的底层原理支撑(编译期,类加载器,对象创建期)

AOP的使用

创建完成spring 应用后,是无法直接使用Spring的AOP的,需要添加两个依赖包

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
</dependency>

其中aspectj中为我们提供了@Pointcut,After, @Aspect,@Before,@Around等注解
aspectjweaver提供了AOP切片执行的主逻辑

AOP的术语

Target目标对象:被代理的原始对象
proxy代理对象:目标对象被织入通知后的产物
JoinPoint连接点:目标对象的所属类中定义的所有方法均为连接点
PointCut切入点:被切面拦截增强的连接点(切入点一定是连接点,连接点不一定是切入点)
Advice通知:增强的逻辑代码,即拦截到目标对象的连接点之后要做的事情

在目标方法前执行@Before
在目标方法后执行@After
在目标方法前后执行@Around
在目标方法返回执行 @AfterReturning
在目标方法异常执行 @AfterThrowing

Aspect 切面:切入点+通知
introduction引介:特殊的通知类型,可以在不修改原有类的代码的前提下,在运行期为原始类动态添加新的属性/方法

Aop切面的使用步骤

  1. 首先在启动类上添加@EnableAspectJAutoProxy注解开启AspectJ
  2. 需要使用@Component将当前类注册成spring组件
  3. 使用@Aspect注解将此类声明成为AOP的切面
  4. 设置增强方法 -->方法上添加通知(advice)例如@Around()
  5. 添加切入点@Around()中表达式@Around("execution(* cn.ton.controller.*.*(..))")为Pointcut(切入点)
  6. 增强方法的参数传入ProceedingJoinPoint(连接点)作为入参,这里Spring会自动将增强方法的上下文封装成该格式传给我们,我们可以通过该参数获取到所想要的目标方法的信息
    在启动类上添加@EnableAspectJAutoProxy注解开启AspectJ
package cn.ton;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@SpringBootApplication
@MapperScan("cn.ton.mapper")
@EnableAspectJAutoProxy
public class FeignDemo1Application {

    public static void main(String[] args) {
        SpringApplication.run(FeignDemo1Application.class, args);
    }

}

设置切面

package cn.ton.aop;
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;

@Slf4j
@Aspect
@Component
public class DemoLogger {

    @Around("execution(* cn.ton.controller.*.*(..))")

    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        final long start = System.currentTimeMillis();
        final Object proceed = joinPoint.proceed();
        log.info("{}()has cost {} ms",joinPoint.getSignature().getName(),System.currentTimeMillis()-start);
        return proceed;
    }
}

切入点(Pointcut)表达式

AspectJ描述符描述
args()限制连接点匹配参数为指定类型的执行方法
@args()限制连接点匹配参数由指定注解标注的执行方法
execution()用于匹配是连接点的执行方法
this()限制连接点匹配的AOP代理的bean引用为指定类型的类
target限制连接点匹配目标对象为指定类型的类
@target()限制连接点匹配特定的执行对象,这些对象对应的类要具有指定类型的注解
within()限制连接点匹配指定的类型
@within()限制连接点匹配指定注解所标注的类型
@annotationn限定匹配带有指定注解的连接点

@Around("execution(* cn.ton.controller.*.*(..))")为例,当使用了execution来描述切入点,这里表示执行在cn.ton.controller包(不包含自包)中任何Spring Compoent对应的方法都会作为切入点实现增强
在这里插入图片描述

execution(* cn.ton.controller..*.*(..)) //.. 还可以表示任意包,controller 包及其子包下的任意类就都会被扫到

自定义注解实现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值