IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 2021SC@SDUSC-SDUDOC-blog05 -> 正文阅读

[Java知识库]2021SC@SDUSC-SDUDOC-blog05

2021SC@SDUSC
此篇记录:AOP by冰弦qwq

AOP

几个基础:

  1. 切入点(Pointcut)
    在哪些类,哪些方法上切入(where)
    通知(Advice)
    在方法执行的什么实际(when:方法前/方法后/方法前后)做什么(what:增强的功能)

  2. 切面(Aspect)
    切面 = 切入点 + 通知,通俗点就是:在什么时机,什么地方,做什么增强!

  3. 织入(Weaving)
    把切面加入到对象,并创建出代理对象的过程。(由 Spring 来完成)

实现底层原理(JDK动态代理)

1、使用JDK动态代理,使用Proxy类里面的方法创建代理对象

static newProxyInstance(ClassLoader, Class<?>[], InvocationHandler);

有三个参数:

  • ClassLoader : 类加载器
  • Class<?>[] : 多个接口
  • InvocationHandler : 实现这个接口,创建代理对象,写增强方法

2、编写JDK动态代理

(1)创建接口,定义方法

(2)创建接口实现类,实现方法

(3)使用proxy

public class MyProxy {

    public static void main(String[] args) {
        Class[] interfaces = {UserInter.class};
        UserImpl user = new UserImpl();
        UserInter inter = (UserInter) Proxy.newProxyInstance(MyProxy.class.getClassLoader(), interfaces, new UserInterProxy(user));
        inter.add(1, 2);
        inter.update("123");
    }

}

// 创建代理
class UserInterProxy implements InvocationHandler {

    private Object object;
    // 把需要代理的对象传入
    // 通过有参构造进行传递
    public UserInterProxy(Object o) {
        this.object = o;
    }

    // 写增强的逻辑
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        // 在方法之前
        System.out.println("invoke before method : " + method.getName() + ":传递的参数..." + Arrays.toString(args));

        Object res = method.invoke(object,args);
        System.out.println(res);

        // 在方法之后
        System.out.println("方法执行之后 : " + object.toString());

        return res;
    }
}

术语

  1. 连接点

    类里面哪些方法可以被增强,这些方法称为连接点

  2. 切入点

    实际被增强的方法,称为切入点

  3. 通知(增强)

    (1)实际增强的逻辑部分称为通知

    (2)通知有多种类型

    • 前置通知
    • 后置通知
    • 环绕通知
    • 异常通知
    • 最终通知 finally
  4. 切面

    是一个动作:把通知应用到切入点的过程

准备工作

Spring框架中,一般基于AspectJ实现AOP操作

(1)什么是AspectJ

  • AspectJ不是Spring组成部分,是一个独立的AOP框架,一般把他和Spring一起使用,进行AOP操作

操作:

(1)基于xml配置文件实现

(2)基于注解方式实现(常用)

步骤:

  1. 引入依赖

切入点表达式

(1)切入点表达式作用:知道对哪个类里面的哪个方法进行增强

(2)语法结构:

execution([权限修饰符][返回类型][类全路径][方法全名]([参数列表]))

示例一:

对com.company.dao.UserDao类里面的add进行增强

execution(* com.company.dao.UserDao.add(..))
// *号表示所有的修饰符

示例二:

对com.company.dao.UserDao类里面的所有方法进行增强

execution(* com.company.dao.UserDao.*(..))
// *号表示所有的修饰符

示例三:

对com.company.dao.包内所有类类里面的所有方法进行增强

execution(* com.company.dao.*.*(..))
// *号表示所有的修饰符

基于注解操作AspectJ

  1. 创建类,在类里面定义方法

    public class User {
        public void add() {
            System.out.println("User.add");
        }
    }
    
  2. 创建增强类(编写增强逻辑)

    • 在增强类里面,创建方法,让不同方法代表不同通知类型

      public class UserProxy {
      
          // 前置通知
          public void before() {
              System.out.println("before...");
          }
      }
      
  • 使用注解创建User和UserProxy对象

  • 在增强类中添加注解@Aspect

    @Component
    public class User {
        public void add() {
            System.out.println("User.add");
        }
    }
    
    @Component
    @Aspect
    public class UserProxy {
    
        // 前置通知
        public void before() {
            System.out.println("before...");
        }
    }
    
  • 在Spring配置文件中开启生成代理对象

<!--开启注解扫描-->
    <context:component-scan base-package="AOP"></context:component-scan>

        <!--开启Aspect生成代理对象-->
        <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
  • 配置不同类型的通知

    在我们的增强类里面,在作为通知方法上面添加通知类型注释,使用切入点表达式配置

    @Component
    @Aspect
    public class UserProxy {
    
        // 前置通知
        // @Before注解表示作为前置通知
        @Before(value = "execution(* AOP.User.add(..))")
        public void before() {
            System.out.println("before...");
        }
    
        @AfterReturning(value = "execution(* AOP.User.add(..))")
        public void afterRet() {
            System.out.println("after Returning...");
        }
    
        @After(value = "execution(* AOP.User.add(..))")
        public void after() {
            System.out.println("after...");
        }
    
        @AfterThrowing(value = "execution(* AOP.User.add(..))")
        public void afterThrowing() {
            System.out.println("throw...");
        }
    
        @Around(value = "execution(* AOP.User.add(..))")
        public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
            System.out.println("around bef...");
    
            proceedingJoinPoint.proceed();
    
            System.out.println("around aft");
        }
        
    }
    
    // ... 结果 : 
    around bef...
    before...
    User.add
    after Returning...
    after...
    around aft
    

注意,如果报错,则afterReturning和aournd后半段不会执行,afterReturning表示方法执行成功才会执行。

而after可以成为最终通知,一定会执行

  1. 对于相同切入点进行抽取

    // 相同切入点抽取
    @Pointcut(value = "execution(* AOP.User.add(..))")
    public void pointDemo() {
    
    }
    
    // 前置通知
    // @Before注解表示作为前置通知
    @Before(value = "pointDemo()")
    public void before() {
    System.out.println("before...");
    }
    
  2. 多个增强类对同一个方法进行增强,可以设置优先级

在增强类上面添加注解@Order(数字值类型),数字越小优先级越高 高优先级会包裹低优先级.

注释实现扫描包配置和启动AspectJ服务:

@Configuration
@ComponentScan(value = {"AOP"})
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class ConfigAop {
}

...

    ApplicationContext context = new 				AnnotationConfigApplicationContext(ConfigAop.class);
User user = context.getBean("user", User.class);
user.add();

基于配置文件操作AOP

by@冰弦qwq

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-10-25 12:24:25  更:2021-10-25 12:26:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:12:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码