• Spring AOP面向切面编程


    定义

    权限切面和日志切面穿插在软件模块中,为原始业务代码添加额外的拓展,随称为面向切面编程

    AOP的做法是将通用、与业务无关的功能抽象封装为切面类

    切面可配置在目标方法的执行、执行后运行,真正做到即插即用。

    AOP的最终目的:在不修改源码的情况下对程序行为进行拓展

    实现

    1、引入依赖

    
        
            org.springframework
            spring-context
            5.3.16
        
     
        
            org.aspectj
            aspectjweaver
            1.9.5
        
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2、模拟业务类
    正常的一些dao/service

    
    import org.springframework.stereotype.Component;
    
    @Component
    public class Say {
    
        public String saying(String s  ){
            return "=========: "+ s;
        }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3、定义Aspect切面类
    主要开启切面、

    package com.wasane.test1;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.springframework.stereotype.Component;
    
    @Component
    @Aspect
    public class SayAop {
    
        @Pointcut("execution(public String com.study.test.Say.saying(..))")
        public void a (){
    
        }
        @Before("a()")
        public void before1(JoinPoint joinPoint){
            String name = joinPoint.getSignature().getName();
            Object  [] args = joinPoint.getArgs();
    
            System.out.println(name+" before "+args[0]);
        }
        @After("a()")
        public void after1(JoinPoint joinPoint){
            String name = joinPoint.getSignature().getName();
            Object [] args = joinPoint.getArgs();
            System.out.println(name+" after ,"+ args[0]);
        }
    
        @Around("a()")
        public void aroud1(ProceedingJoinPoint joinPoint) throws Throwable {
            String name = joinPoint.getSignature().getName();
    
            System.out.println(name+" aroud start");
            Object t =  joinPoint.proceed();
            System.out.println(name+" aroud return : "+ t);
            System.out.println(name+" aroud end");
        }
    
    
    
        @AfterReturning(value = "a()" , returning = "return2")
        public void return1(JoinPoint joinPoint , String return2){
            String name = joinPoint.getSignature().getName();
    
            System.out.println(name+"  return  :"+ return2 );
        }
    
        @AfterThrowing(value = "a()" , throwing = "excep")
        public void exception1(JoinPoint joinPoint , Exception excep){
            String name = joinPoint.getSignature().getName();
    
            System.out.println(name+"  Exception  :"+ excep );
        }
    
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    4、xml或这注解方法开启切面编程,因为spring是默认不开启的
    在这里插入图片描述
    或者

    package com.wasane.test1;
    
    
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.EnableAspectJAutoProxy;
    
    @Configuration
    @EnableAspectJAutoProxy
    @ComponentScan("com....")
    public class MyConfig {
    
    
    
    
    
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    5、测试

    
    
    import com.wasane.test1.MyConfig;
    import com.wasane.test1.Say;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = {MyConfig.class})
    public class AopTest {
    
        @Autowired
        Say s ;
    
        @Test
        public void test1(){
            System.out.println(s.saying(" gooos " ));
        }
    
    
    
    
    
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    AOP关键概念

    注解back
    Aspect切面
    Target Class/Method目标类
    PointCut切入点
    JoinPoint连接点
    Advice通知

    Aspect类的方法名随意,返回参数为void/Object,但是参数必须为(JoinPoint joinPoint);

    JoinPoint对象

    joinPoint.getTarget();//从IOc容器内的目标对象
    joinPoint.getSignature();//获取目标方法
    joinPoint.getArgs();//获取目标

    PointCut切点的execution()表达式

    execution()表达式,规定Aspect表达式的应用类的范围

    类修饰符public 返回值String 包范围-类名-方法名-方法的参数形式com.study.test.Say.saying(…)这个指的是saying方法所有参数形式都应用

    @Pointcut("execution(public String com.study.test.Say.saying(..))")
    
    • 1

    Aspect的五种通知类型

    Before Advice 前置通知 对应注解@Before
    After Returning Advice 返回后通知
    After Throwing Advice 异常通知
    After Advice 后置通知
    Around Advice环绕通知,最强大通知,自定义通知执行时机,可决定目标方法是否运行

    实现原理

    Spring基于代理模式实现功能动态拓展AOP,包含两种形式:
    1.目标类有接口,通过JDK动态代理实现功能拓展
    2.目标类没有接口,通过CGLib组件实现功能拓展

    CGLib

    CGLib是运行时字节码增强技术

    Spring AOP拓展无接口类使用CGLib

    AOP会运行时生成目标继承类字节码的方式进行行为拓展

  • 相关阅读:
    十、Spring Boot 安全管理(5)
    HTTP协议中Gzip格式的流量分析与识别
    【672. 灯泡开关 Ⅱ】
    pat考完了
    【蓝桥杯入门记录】动态数码管例程
    【软件测试】01 -- 软件生命周期、软件开发模型
    力扣刷题记录41.1-----101. 对称二叉树
    数据结构学习笔记——数据结构概论
    Web安全——Web安全漏洞与利用上篇(仅供学习)
    工业交换机一般的价格是多少呢?
  • 原文地址:https://blog.csdn.net/weixin_43206161/article/details/126445411