引入AOP--代理的比较

本文深入探讨了面向切面编程(AOP)的概念及其在软件开发中的应用,介绍了三种主要的代理模式:静态代理、JDK动态代理和CGLib动态代理。详细解释了每种模式的工作原理和适用场景,并对比了它们之间的性能差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AOP(面向切面编程):

    切面:从业务逻辑分离出去的横切逻辑。典型:性能监控,日志管理,权限控制,可以从核心的业务逻辑中分离出去。

    通过AOP可以解决代码耦合问题,使职责更加单一。

对于需要增强的代码,我们通常有三种解决方案:

(1)静态代理

(2)JDK动态代理

(3)CGLib动态代理

静态代理:

   由程序员创建生成源代码,再对其进行编译,再程序运行时,class文件就已经存在了。(创建代理类去进行代理,但每有一个需要代理的类,都要创建相应的代理类。随着后期的发展,这种代理类会越来越多。这种方式过于繁琐,需要优化的是只生成一个代理类,让需要被代理的类都依赖这个代理类,这就需要动态代理)。

JDK动态代理:

在程序运行时,通过反射机制动态生成代理。避免编写各个繁琐的静态代理类,

动态代理三个步骤:

(1)编写自定义的InvocationHandler来实现InvocationHandler接口

(2)创建动态代理对象。

(3)代理对象调用

public class MyinvocationHandler implements InvocationHandler {
    private Object target;

    public MyinvocationHandler(Object target) {
        this.target = target;
    }

    /**
     *获取代理对象
     */
    public Object getProxy(){
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before();
        Object rs = method.invoke(target,args);
        after();
        return rs;
    }

    public void before(){
        System.out.println("开始前");
    }

    public void after(){
        System.out.println("开始后");
    }
}
JDK动态代理只能代理具有接口的类,不能代理没有接口的类,开源的CGLIb类库具有代理没有接口的类的能力,弥补了JDK的不足。

CGLIB动态代理:采用了底层的字节码技术,通过字节码技术为一个类创建子类,并在子类中对所有方法进行拦截来实现对父类方法的拦截,从而织入横切逻辑,是实现AOP的基础。

public class cglibProxy implements MethodInterceptor {
    private Enhancer enhancer = new Enhancer();

    public Object getProxy(Class clazz){
        //传入父类字节码
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        //字节码技术创建子类
        return enhancer.create();

    }
    //intercept用于拦截方法的调用(这里可以进行增强的处理)
    public Object intercept(Object obj, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("增强前");
        //调用父类的目标方法
        Object result = methodProxy.invokeSuper(obj,objects);
        System.out.println("增强后");
        return result;
    }
}
getProxy()方法通过传入父类的字节码,创建其子类,intercept()通过对子类方法的拦截来拦截对父类目标方法的调用,顺势织入横切逻辑,达到增强的效果。
对于JDK,CGLib两种动态代理:

  
  
 JDK动态代理CGLIB动态代理
接口必须不需要
性能比cglib低 比JDK高
耗时耗时相对短耗时长
对于单例的对象,因为无需频繁创建对象,用CGLib合适,CGLIB对于final修饰的类无法进行代理。










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值