暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Spring系列(一)——Spring AOP

喝一杯咖啡吧 2020-05-09
218

Spring AOP

  • AOP

    • AOP是什么

    • AOP的应用场景

  • Spring AOP和AspectJ

    • AOP,Spring AOP,AspectJ三者之间的关系

    • Spring AOP的底层技术

    • Spring AOP的一些基本概念

  • Spring AOP案例


AOP

AOP是什么

是一种面向切面编程的思想,传统的OOP开发中的代码逻辑是自上而下的,而这些过程会产生一些横切性问题,这些横切性的问题和我们的主业务逻辑关系不大,这些横切性问题不会影响到主逻辑实现的,但是会散落到代码的各个部分,难以维护。AOP是处理一些横切性问题,AOP的编程思想就是把这些问题和主业务逻辑分开,达到与主业务逻辑解耦的目的。使代码的重用性和开发效率更高。

AOP的应用场景

  • 日志记录

  • 权限验证

  • 事务管理

Spring AOP和AspectJ

AOP,Spring AOP,AspectJ三者之间的关系

  • AOP是一种思想。

  • SpringAop、AspectJ都是AOP的实现,Spring AOP有自己的语法,但是语法复杂,所以Spring AOP借助了AspectJ的注解,但是底层实现还是自己的。

  • Spring AOP提供了两种编程风格

@AspectJ support         ------------>利用aspectj的注解
Schema-based AOP support ----------->xml aop:config 命名空间

复制

Spring AOP的底层技术

使用了动态代理,包含jdk动态代理和Cglib动态代理。并且在初始化时期织入。

Spring AOP的一些基本概念

  • aspect:切面

    • 在类上声明 @Aspect

    • 交给Spring管理 @Component

  • pointcut:切点

    • 连接点的集合

    • 告诉通知连接点在哪里

    • 切点表达式决定joinpoint的数量

  • joinpoint:连接点

    • 目标对象的方法

    • 要关注和增强的方法,也就是我们要作用的点。

  • weaving:织入,把代理逻辑加入到目标对象上的过程

  • target:目标对象(原始对象)

  • aop proxy:代理对象,包含了原始对象的代码和增加后的代码的那个对象

  • advice:通知(位置 + logic)

  • advice通知类型

    • Before 连接点执行之前,

    • After 连接点正常执行之后

    • After throwing 执行抛出异常的时候

    • After finally 无论连接点是正常退出还是异常退出,都执行

    • Around advice 围绕连接点执行,例如方法调用。这是最有用的切面方式。around通知可以在方法调用之前和之后执行自定义行为。它还负责选择是继续加入点还是通过返回自己的返回值或抛出异常来快速建议的方法执行。

Spring AOP案例

  • 创建maven项目,并引入依赖

<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.11.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.2</version>
</dependency>
</dependencies>

复制
  • 使用Java Config启用@AspectJ支持

package com.example.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@ComponentScan("com.example")
@EnableAspectJAutoProxy
public class AppConfig {
}

复制
  • 声明一个切面类

package com.example.config;

import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
* 声明一个切面
* 此切面一定要交给Spring管理
*/

@Aspect
@Component
public class TxAspect {
@Pointcut("execution(* com.example.dao.*.*(..))")
public void pointCut(){

}
@After("com.example.config.TxAspect.pointCut()")
public void after(){
System.out.println("after...");
}
/**
* before通知,在pintCut切入点前执行
*/

@Before("com.example.config.TxAspect.pointCut()")
public void before(){
System.out.println("before...");
}
@AfterThrowing("com.example.config.TxAspect.pointCut()")
public void doRecoveryActions(){
System.out.println("异常");
}
}

复制
  • 新建dao接口和IndexDao类

package com.example.dao;

public interface Index {
void query();
}

复制
package com.example.dao;

import org.springframework.stereotype.Component;

@Component
public class IndexDao implements Index {
@Override
public void query(){
System.out.println("dao----query");
System.out.println(1/0);
}
}

复制
  • 新建测试类

package com.example.test;

import com.example.config.AppConfig;
import com.example.dao.Index;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Index dao1 = context.getBean(Index.class);
dao1.query();
}
}

复制
  • 运行结果如下


文章转载自喝一杯咖啡吧,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论