Spring中AOP思想

AOP思想

什么是AOP

是一种设计思想,是oop一种补充;AOP采取横向收取机制,取代了传统纵向继承体系重复性代码。

面向切面编程,传统的oop开发中的代码逻辑是自上而下的,这些自上而下的过程中会产生一些重复的横切性问题,这些横切的问题和我们主要的业务逻辑关系不大,会散落在代码的各个功能地方,维护麻烦;AOP是编程思想就是把业务逻辑和横切问题进行分离,从而达到解耦的目的,提高代码的重用性和开发效率。

AOP应用场景

  • 日志记录
  • 权限管理
  • 事务管理
  • 性能监控
  • 缓存优化(第一次访问,查询数据库,放入缓存,第二次以后访问从缓存返回)

AOP相关术语

  • 连接点-Joinpoint:其实就是业务方法(目标对象中的方法);Spring中只支持方法类型的连接点

  • 切入点-Pointcut:如果通知定义了切面的“什么”和“何时”,那么切点定义了“何处”;对joinpoint进行拦截的定义

  • 通知-Advice:定义了切面是什么,以及何时使用

    分为:前置通知、后置通知、返回通知、异常通知、环绕通知

  • 引介-Introduction:允许我们向现有的类添加新的方法或属性

  • 目标对象-target:被切入的对象,代理的目标对象

  • 织入-Weaving:把切面应用到目标对象并创建新的代理对象的过程

  • 代理-Proxy:一个类被AOP织入增强后,产生的一个结果代理类

  • 切面-Aspect:通知和切点的结合

AOP底层实现的原理

动态代理

spring aop实现原理

如果组件定义了接口,则使用jdk创建动态代理;如果没有接口,则使用CGlib创建动态代理

SpringAOP案例

  1. 将业务逻辑组件和切面类都加入到容器中;告诉Spring哪个是切面类(@Aspect)
  2. 在切面类上的每一个通知方法上标注通知注解,告诉Spring何时何地运行(切入点表达式)
  3. 开启基于注解的aop模式;@EnableAspectJAutoProxy

maven依赖


      org.springframework
      spring-aspects
      XXXX
 

业务类(目标对象)

public class MathCalculator {
    public int div(int i,int j){
        System.out.println("MathCalculator...div...");
        return i/j; 
    }
}

切面类(切面)

@Aspect
public class LogAspects {
    
        //抽取公共的切入点表达式
        //1、本类引用
        //2、其他的切面引用
        @Pointcut("execution(public int com.dwb.aop.MathCalculator.*(..))")
        public void pointCut(){};
        
        //@Before在目标方法之前切入;切入点表达式(指定在哪个方法切入)
        @Before("pointCut()")
        public void logStart(JoinPoint joinPoint){
            Object[] args = joinPoint.getArgs();
            System.out.println(""+joinPoint.getSignature().getName()+"运行。。。@Before:参数列表是:{"+Arrays.asList(args)+"}");
        }
        
        @After("com.dwb.aop.LogAspects.pointCut()")
        public void logEnd(JoinPoint joinPoint){
            System.out.println(""+joinPoint.getSignature().getName()+"结束。。。@After");
        }
        
        //JoinPoint一定要出现在参数表的第一位
        @AfterReturning(value="pointCut()",returning="result")
        public void logReturn(JoinPoint joinPoint,Object result){
            System.out.println(""+joinPoint.getSignature().getName()+"正常返回。。。@AfterReturning:运行结果:{"+result+"}");
        }
        @AfterThrowing(value="pointCut()",throwing="exception")
        public void logException(JoinPoint joinPoint,Exception exception){
            System.out.println(""+joinPoint.getSignature().getName()+"异常。。。异常信息:{"+exception+"}");
        }

}

说明:JoinPoint一定位于通知形参的第一个
​ 目标对象的形参、异常、返回值等通过连接点获取 joinpoint获取

测试类

//该注解很重要
@EnableAspectJAutoProxy
@Configuration
public class Client {
     
    //业务逻辑类加入容器中
    @Bean
    public MathCalculator calculator(){
        return new MathCalculator();
    }

    //切面类加入到容器中
    @Bean
    public LogAspects logAspects(){
        return new LogAspects();
    }
    
    AnnotationConfigApplicationContext applicationContext 
        = new AnnotationConfigApplicationContext(Client.class);
        
        //1、不要自己创建对象
//      MathCalculator mathCalculator = new MathCalculator();
//      mathCalculator.div(1, 1);
        MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);
        
        mathCalculator.div(8, 2);
        
        applicationContext.close();
}

说明:Spring中,aop,对象必须通过ioc创建,自己new出来,不会执行切面不会生效;因为aop底层是动态代理实现

输出结果:

div运行。。。@Before:参数列表是:{[8, 2]}
MathCalculator...div...
div结束。。。@After
div正常返回。。。@AfterReturning:运行结果:{4}

你可能感兴趣的:(Spring中AOP思想)