栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

对Spring AOP的理解

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

对Spring AOP的理解

AOP
  • AOP是什么?
  • AOP的相关名词
    • 切面
    • 切入点
    • 通知
    • 切面
    • 目标
    • 代理
  • StringAOP的实现
  • 代理
    • jdk代理
      • JDK代理的优缺点
    • cglib代理

AOP是什么?

    AOP是Spring两大特性之一,他的意思为面向切面编程。使用AOP可以抽取一些公共模块出来,减少公共模块和业务代码的耦合。利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各 部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。 AOP、OOP 在字面上虽然非常类似,但却是面向不同领域的两种设计思想。OOP (面向对象编程)针对业务处理过程的实体及其属性和行为进行抽象封装,以获 得更加清晰高效的逻辑单元划分。

AOP的相关名词 切面

类中可以被增强的方法,这个方法就被称为连接点

切入点

类中有很多方法可以被增强,但实际中只有 add 和 update被增了,那么 add 和 update 方法就被称为切入点(实际实现的连接点)

通知

通知是指一个切面在特定的连接点要做的事情(增强的功能)。通知分为方法执行前通知,方法执行后通知,环绕通知、异常通知和返回通知等.

切面

把通知添加到切入点的过程叫切面.

目标

代理的目标对象(要增强的类)

代理

向目标对象应用通知之后创建的代理对象

StringAOP的实现

具体实现方式翻阅之前写的博客
AOP和事务管理

代理

    SpringAOP是通过代理来实现面向切面编程的,它使用的代理有两种,JDK代理和CGlib代理。当我们的bean对象实现了某一接口后,Spring默认将采用Jdk动态代理,当我们的bean对象没有实现接口时,默认将采用CGLIB代理,Spring也支持我们在bean对象实现了接口时也强制的使用CGLIB代理。

jdk代理

    JDK动态代理基于拦截器和反射来实现。代理类必须要实现InvocationHandler接口,重写invoke()方法。

代码实现:

接口类:UserDao

//抽象用户操作定义
public interface UserDao {
    void saveUser();
}

两个实现类,普通用户实现UserDaoImpl和VIP用户实现VipUserDaoImpl

public class UserDaoImpl implements UserDao{

    @Override
    public void saveUser() {
        System.out.println("普通用户实现");
        //增加新功能要在每个实现类里面写
        //saveLog()
    }
}

public class VipUserDaoImpl implements UserDao{
    @Override
    public void saveUser() {
        System.out.println("VIP用户实现");
        //增加新功能要在每个实现类里面写
        //saveLog()
    }
}

动态代理类Dtproxy

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

//实现java.lang包下的reflect类的InvocationHandler接口
public class Dtproxy implements InvocationHandler {

    Object object;//真实对象
    public Dtproxy(Object object){
        this.object = object;
    }

    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("之前开始事务");
        method.invoke(object);
        System.out.println("之后提交事务");
        return proxy;
    }
    
}

测试类Test:

public class Test {
    public static void main(String[] args) {
        VipUserDaoImpl vipUserDao = new VipUserDaoImpl();
        InvocationHandler dtproxy = new Dtproxy(vipUserDao);

        //创建代理对象
        UserDao userDao = (UserDao)Proxy.newProxyInstance(Dtproxy.class.getClassLoader(),VipUserDaoImpl.class.getInterfaces(),dtproxy);
        userDao.saveUser();
    }
}
JDK代理的优缺点

    JDK代理是通过反射来实现,JDK通过反射,生成一个代理类,这个代理类实现了原来那个类的所有接口,并对接口定义的方法进行代理。当我们通过代理对象执行原来那个类的方法时,代理类底层会通过反射机制,回调我们实现的InvocationHandler接口的invoke方法。
优点:

  1. JDK动态代理是JDK原生的,不需要任何依赖即可使用;
  2. 通过反射机制生成代理类的速度要比CGLib操作字节码生成代理类的速度更快;

缺点:

  1. 如果要使用JDK动态代理,被代理的类必须实现了接口,否则无法代理;
  2. JDK代理必须要有实现类实现目标接口。
  3. JDK动态代理执行代理方法时,需要通过反射机制进行回调,此时方法执行的效率比较低;
cglib代理

CGLIB实现动态代理的原理是:底层采用ASM字节码生成框架,直接对需要代理的类的字节码进行操作,生成这个类的一个子类,并且重写类的所有方法。
优点:

  1. 使用CGLib代理的类,不需要实现接口,因为CGLib生成的代理类是直接继承自需要被代理的类;
  2. CGLib生成的代理类是原来那个类的子类,这就意味着这个代理类可以为原来那个类中,所有能够被子类重写的方法进行代理;
  3. CGLib生成的代理类,和我们自己编写并编译的类没有太大区别,对方法的调用和直接调用普通类的方式一致,所以CGLib执行代理方法的效率要高于JDK的动态代理;

缺点

  1. 由于CGLib的代理类使用的是继承,这也就意味着如果需要被代理的类是一个final类,则无法使用CGLib代理
  2. 由于CGLib实现代理方法的方式是重写父类的方法,所以无法对final方法,或者private方法进行代理,因为子类无法重写这些方法;
  3. CGLib生成代理类的方式是通过操作字节码,这种方式生成代理类的速度要比JDK通过反射生成代理类的速度更慢;
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/975528.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号