SpringAOP总结

1.AOP概述

①OOP(Object Oriented Programming)面向对象编程

②AOP(Aspect Oriented Programming)面向切面编程,一种编程范式,指导开发者如何组织程序结构

③作用:在不惊动原始设计的基础上为其进行功能增强

④Spring理念:无入侵式/无侵入式

⑤原理:动态代理

⑥应用:1. 日志 2. 异常捕获、处理 3. 监控统计代码 4. 记录过程。

概念概述

1)连接点(JoinPoint):正在执行的方法,例如:update()、delete()、select()等都是连接点。

2)切入点(Pointcut):进行功能增强了的方法,例如:update()、delete()方法,select()方法没有被增强所以不是切入点,但是是连接点。

在SpringAOP中,一个切入点可以只描述一个具体方法,也可以匹配多个方法

--一个具体方法:com.xixi.dao包下的BookDao接口中的无形参无返回值的save方法

--匹配多个方法:所有的save方法,所有的get开头的方法,所有以Dao结尾的接口中的任意方法,所有带有一个参数的方法

3)通知(Advice):在切入点前后执行的操作,也就是增强的共性功能在SpringAOP中,功能最终以方法的形式呈现

4)通知类:通知方法所在的类叫做通知类

5)切面(Aspect):描述通知与切入点的对应关系,也就是哪些通知方法对应哪些切入点方法。

2.案例

要求:写一个计算器功能:计算除法。并且用日志方式打印传递的参数、和结果、结束后通知用户计算完成!如果出现异常打印异常信息。

①导入aop相关坐标

②定义业务接口与实现类

③定义通知类,制作通知方法

④定义切入点表达式、配置切面(绑定切入点与通知关系)

⑤在配置类中进行Spring注解包扫描和开启AOP功能

步骤一:导入aop坐标

<!--spring核心依赖,会将spring-aop传递进来-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>
    <!--切入点表达式依赖,目的是找到切入点方法,也就是找到要增强的方法-->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.4</version>
    </dependency>

步骤二:在配置类中进行Spring注解包扫描并开启AOP功能

@EnableAspectJAutoProxy开启注解开发AOP功能

@Configuration
@ComponentScan("com.gaohe")
//开启注解开发AOP功能
@EnableAspectJAutoProxy
public class SpringConfig {
}

步骤三:定义dao接口和实现类

//接口
public interface Counter {
    int add(int i,int j);
    int div(int i,int j);
}

@Repository 是 Spring 提供的专门用于数据访问对象(DAO)的注解,用于标识一个数据访问对象的 Bean。在这里,表示将指定的组件或 Bean 的名称命名为“counter”。这个名称可以在其他组件或类中使用来引用这个指定的组件或 Bean。

而 @Component 是 Spring 提供的通用注解,用于标识一个普通的 Spring Bean。虽然 @Repository 是 @Component 的一个特例,但使用 @Repository 能够更清晰地表达代码的意图,也更容易被其他开发者理解。

//实现类
@Repository("counter")
public class CounterImpl implements Counter {
    @Override
    public int add(int i, int j) {
        int r =  i+j;
        return r;
    }
    @Override
    public int div(int i, int j) {
        int r =  i/j;
        return r;
    }
}

步骤四:定义通知类,制作通知方法

@Component 是 Spring 提供的通用注解,用于标识一个普通的 Spring Bean。当一个类被标记为 @Component,Spring 将会自动扫描并将其实例化为一个 Bean,并将其纳入 Spring IoC 容器中进行管理。这样其他组件就可以通过依赖注入的方式获取到这个 Bean 的实例,方便在程序中进行调用和使用。@Component 是最常用的 Spring 注解之一,适用于多种类型的 Bean。

@Aspect 是 Spring AOP(面向切面编程)模块中的注解,用于定义切面(Aspect)。切面是横切关注点的模块化,这些关注点跨越多个对象,比如事务处理、日志记录等。通过 @Aspect 注解标识的类可以包含切点(Pointcut)和通知(Advice),用来定义在哪些连接点(Join point)上执行什么样的逻辑。在 Spring 中,@Aspect 注解常常与其他注解一起使用,比如@Before、@After、@Around等,来定义不同类型的通知。通过使用 @Aspect 注解,可以实现对代码的横切关注点进行模块化,提高代码的灵活性和可维护性。

@Pointcut 是 Spring AOP(面向切面编程)中的注解,用于定义切点(Pointcut)。切点表示在应用程序中的哪些连接点(Join point)上应用通知(Advice)。@Pointcut 注解通过指定一个切入点表达式(Pointcut expression)来定义具体的连接点,从而告诉 Spring 在哪里执行切面逻辑。

@Before 是 Spring AOP 中的注解,用于定义前置通知(Before advice)。@Before 注解可以与 @Pointcut 注解一起使用,指定在某个切点(Pointcut)执行之前应该执行的逻辑。在本案例中,@Before(“pt()”) 表示在指定的切入点(Pointcut)pt() 执行之前,应该执行的逻辑。通过 @Before 注解,可以实现在目标方法执行前添加特定逻辑,比如权限检查、日志记录等功能。

//通知类必须配置成Spring管理的bean
@Component
//设置当前类为切面类
@Aspect
public class MyAdvice {
    //设置切入点,@Pointcut注解要求配置在方法上方
    @Pointcut("execution(void com.gaohe.dao.Counter.add(..))")
    private void pt(){}
​
    //设置在切入点pt()的前面运行当前操作(前置通知)
    @Before("pt()")
    public void before(JoinPoint jp){
//或其目标对象
        System.out.println(jp.getSignature());
    }
}
​

通知方法

//设置当前通知方法与切入点之间的绑定关系,当前通知方法在原始切入点方法前运行
@Before("pt()")
public void before(JoinPoint jp) {
    System.out.println("before advice ...");
}


​
//设置当前通知方法与切入点之间的绑定关系,当前通知方法在原始切入点方法后运行
@After("pt()")
public void after(JoinPoint jp) {
    System.out.println("after advice ...");
}


​
//设置当前通知方法与切入点之间的绑定关系,当前通知方法在原始切入点方法正常执行完毕后运行
//  value 切点方法   returning 返回的值Object
//  returning 的名字和参数的名字必须一致
//  JoinPoint 如果出现必须在第一位
@AfterReturning(value = "pt()",returning = "r")
public void method4(JoinPoint jp,Object r){
    System.out.println("返回通知"+r);
    System.out.println(jp.getSignature().getName());
}


​
//设置当前通知方法与切入点之间的绑定关系,当前通知方法在原始切入点方法运行抛出异常后执行
//  value 切点方法  throwing 返回的异常对象的名字
//  异常对象的名字  和参数对象的名字一致
//  JoinPoint 如果出现必须在第一位
@AfterThrowing("pt()",throwing = "t")
public void afterThrowing(JoinPoint jp,Throwable t) {
    System.out.println("afterThrowing advice ...");
}


​
//设置当前通知方法与切入点之间的绑定关系,当前通知方法在原始切入点方法前后运行@Around("pt()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
    System.out.println("around before advice ...");
    Object ret = pjp.proceed();
    System.out.println("around after advice ...");
    return ret;
}

注意:

  1. 环绕通知方法形参必须是ProceedingJoinPoint,表示正在执行的连接点,使用该对象的proceed()方法表示对原始对象方法进行调用,返回值为原始对象方法的返回值。

  2. 环绕通知方法的返回值建议写成Object类型,用于将原始对象方法的返回值进行返回,哪里使用代理对象就返回到哪里。

3.AOP核心概念

目标对象:被代理点对象,也叫原始对象,该对象中的方法没有任何功能增强

代理对象:代理后生成的对象,由Spring帮我们创建代理对象

4.AOP工作流程

  • 9
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值