对Spring的面向切面aop的理解

一:aop即面向切面编程,把除了业务核心的方法抽取出来,进行方法的复用。也就是在业务核心方法代码不改变的情况下对方法进行功能的增强

二:aop的底层是动态代理,也就是通过代理类来对方法进行增强(JDK动态代理)

代理模式的基本思路:被代理类A类与代理类ProxyA,在ProxyA中创建一个与A类中被代理的方法同名的成员方法,并且在这个同名方法中即加入自己要增强的逻辑实现,同时调用A中要被代理的方法,使用时调用该代理类的代理方法即可。根据创建代理类实例的方法的不同,代理就分为静态代理和动态代理,前者时直接手动生成的,这样当需要被代理类很多时,就要创建很多个代理类,后者时通过反射,运行时动态生成的,但是静态代理与动态代理的基本逻辑是一样的。

三:aop的几个概念:

AOP即面向切面编程,切面即是增强类切入点表达式所在的面叫切面,一个切面有很多个通知,切面上的通知可以被织入到被增强的类,织入到哪里可以通过切入点表达式来指定切点,这些通知则是与业务逻辑无关却又不可缺少的代码。而切点就是被增强类的所有方法,而切入点就是被增强的具体某一个方法,功能增强即对该方法进行补充,通知则是补充的内容(根据通知在方法的位置可以分为前置通知,后置通知等)

SpringAOP的基本操作:(注解式)

        1.编写一个切面:一般是一个java普通类(@Aspect)

        2.把切面加入Spring容器:@Component

        3.编写通知:(java方法)

        4.织入通知(切面)到被增强类:使用切点表达式(@Before(execution("表达式")))

               也可以在切面使用一个空方法配置切入点表达式(@Pointcut),使用切入点表达式声明织入点,然后直接在通知上调用方法,如@Before("test()")

        (@annotation()注解的作用是把通知织入标注了特定注解的所有类,如@Before("@annotation(xxx.xxx.myAnnotation)"))

spring事务管理底层就是aop功能增强,通过声明某方法为事务方法,就会通过反射创建代理类,由代理类去执行事务的相关操作

四:原生的JDK动态代理(生成一个proxy代理类,由代理类调用被代理的方法)

生成一个proxy代理类的参数(Proxy类是java自带的,可以通过该静态类的静态方法生成相应代理类)

          (1)控制器的类加载器:被代理类的类加载器

          (2)被代理类实现的接口:可以生成一个与代理类相同的方法并实现要代理的功能

          (3)控制器:实质是InvocationHandler的实现类,运行时生成的代理类运行时会创建一个与被代理方法同名的方法,该方法的实现逻辑是调用该控制器的invoke方法

        注意:InvocationHandler实现类并不是代理类,代理类是通过Proxy类生成的,InvocationHandler实现类只是一个代理类与被代理类的中间层而已,该类的invoke方法就是实质就是代理类的代理方法的实现。动态生成的代理类会把该实现加进自己类中

//实现功能的增强
    public Class ProxyA implements InvocationHandler{
        
       @Override
        public Object invoke(Object proxy,Method method,Object[] args){
        
        //逻辑增强实现

        //执行被代理方法
        method.invoke()
    }


//在InvocationHandler实现类的构造函数中创建代理类实例,该代理类实例会自动生成一个与被代理方法
//同名的方法,在该方法中实际会调用InvocationHandler实现类中的invoke()方法
    public ProxyA(){

    return Proxy.newProxyInstance(相应参数)

    }
}

//外部调用时,直接通过new ProxyA()就可以创建代理类,但是ProxyA并不是真正的代理类,代理类是通过Proxy.newProxyInstance()生成的!!!



静态代理与动态代理的区别:静态代理会把代理类与被代理类直接绑定,代理类需要持有被代理类的成员变量,即使再增强一个一摸一样的功能时,依然要再创建一个代理类来对另外一个被代理类进行功能增强,也就是所谓的代理一百个类,就要创建一百给代理类;

而动态代理,由于使用了反射技术,代理类中是不需要持有被代理类的对象的(代理类与被代理类中间隔了一个控制器实现类,代理类并不需要持有被代理类,控制器实现类持有就可以了,并且控制器通过method对象就可以拿到被代理的方法),也就是说,无论被代理方法如何变动,改动控制器就可以了,是不需要改动代理类的。aop实质就是动态代理的一个经典实现,可以把要增强的逻辑和业务完全分开来,运行时,直接织入通知即可。

另外:原生jdk的动态代理代理的必须是基于接口的,mybatis的sqlsession.getMapper(xxxMapper.class)返回的也是一个代理类,传入一个接口参数来指定接口即可,其他参数已经被封装好了

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值