AOP的底层原理:动态代理

AOP的底层原理:动态代理

使用动态代理时会生成一个动态代理类

动态代理类是在程序运行期间由jvm通过反射等机制动态生成的。

所以不存在代理类的字节码文件(因为没有经历编译阶段),代理对象和真实对象的关系是在程序运行期间才确定的。

JDK动态代理

JDK的代理方式 只能针对接口,目标必须实现接口,同时代理类也实现了和目标对象同样的接口

package ThreadPoolLearn;

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

public class JdkProxyDemo {
    interface Foo{
        void foo();
    }
   static class Target implements Foo{

       @Override
       public void foo() {
           System.out.println("target foo");
       }
   }
    //JDK的代理方式 只能针对接口,目标必须实现接口,同时代理类也实现了和目标对象同样的接口
    //目标类可以是final
    public static void main(String[] args) {
        //目标类对象
        Target target=new Target();
        ClassLoader loader=JdkProxyDemo.class.getClassLoader();
        //动态代理类是在程序运行期间由jvm通过反射等机制动态生成的,
        //所以不存在代理类的字节码文件(因为没有经历编译阶段),代理对象和真实对象的关系是在程序运行期间才确定的。
        //下面的方法最终会返回实现接口的代理对象
        Foo proxy=(Foo) Proxy.newProxyInstance(loader/*类加载器,用来加载运行期间生成的字节码*/, new Class[]{Foo.class}/*要实现的接口*/,
                new InvocationHandler()/*用于执行代理类增强的方法*/ {
            @Override
            public Object invoke(Object proxy/*代理对象自己*/, Method method/*正在执行的方法对象*/, Object[] args/*方法中的实际参数*/) throws Throwable {
                System.out.println("before");
                //将代理类和要增强的类结合起来
                Object result=method.invoke(target,args);
                return result;//让代理类放回目标方法执行的结果
            }
        });
        proxy.foo();
    }
}
Cglib动态代理

​ 通过Enhancer创建代理对象
​ 创建的代理对象是被代理对象的子类形
​ 因此目标类不能用final修饰
​ 目标方法也不能用final修饰,代理类代理该方法是重写方法

​ 能通过methodProxy,避免反射调用目标,可以提高效率
​ Object result2=methodProxy.invoke(target,args);

package ThreadPoolLearn;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CglibProxyDemo {
    static class Target{
        public void foo(){
            System.out.println("target foo");
        }
    }

    public static void main(String[] args) {
        Target target=new Target();
        //通过Enhancer创建代理对象
        //创建的代理对象时被代理对象的子类形
        //因此目标类不能用final修饰
        //目标方法也不能用final修饰,代理类代理该方法是重写方法
        Target proxy=(Target) Enhancer.create(Target.class/*目标类*/, new MethodInterceptor()/*用于执行代理类增强的方法*/ {
            @Override
            public Object intercept(Object p/*代表代理类自己*/, Method method/*代理类中执行的方法*/, Object[] args/*方法执行时的实际参数*/,
                                    MethodProxy methodProxy) throws Throwable {
                System.out.println("before ");
                Object result=method.invoke(target,args);//使用方法反射调用目标
                //methodProxy,避免反射调用目标
                Object result2=methodProxy.invoke(target,args);
                //避免反射调用目标,使用代理对象自己
                Object result3=methodProxy.invokeSuper(p,args);
                System.out.println("after ");
                return null;
            }
        });
        proxy.foo();
    }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值