java的三种代理模式(AOP原理)

一、静态代理

1个接口+2实现类,不灵活:会有很多代理类,且当接口增加新方法时,所有代理类都要改。

二、JDK动态代理

     1.又叫动态代理、JDK代理。 目标对象一定要实现接口(否则只能用CGLib动态代理),代理类是 java.lang.reflect.Proxy类。

     a.定义接口;
     b.创建真实委托类,实现接口;
     c.创建中间类,实现InvocationHandler接口,重写invoke方法,同时可以在invoke方法中做增强操作:

class MyInvocationHandle implements InvocationHandler{
    private Object target;
    public void setTarget(Object target) {
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // proxy就是[目标对象],method就是调用目标对象中方法,args就是调用目标对象中方法的参数
            System.out.println("增强1...");
            Object invoke = method.invoke(target, args);    //实际执行
            System.out.println("增强2...");
            return invoke;
    }
}

     4.通过Proxy类新建代理对象:Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h); 

 class MyProxyFactory{
    public static Object getProxy(Object target) {
        MyInvocationHandle handle = new MyInvocationHandle();
        handle.setTarget(target);
        Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handle);
        return proxy;
    }
 }

三、CGLib动态代理

    1.Code Generation Library。Cglib以目标类的子类方式实现代理,代理的目标类可以实现接口也可以不实现,但是目标类不能为final(无法继承)。目标对象的方法如果为final/static,那么就不会被拦截,即不会执行目标对象额外的业务方法(final方法和static方法在内存中独一份,不能被重写)。

    2.Cglib包的底层是动态字节码操作,通过ASM字节码处理框架,修改代理对象类的字节码,生成子类来处理。

    3. proxy.invokeSuper(obj, args); 调用父类的方法,就是目标对象的方法,而不是调用动态生成的代理子类的重写后的方法。

        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(String.class);
        enhancer.setCallback(new net.sf.cglib.proxy.MethodInterceptor() {
            @Override
            public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                System.out.println("pre.....");
                Object invoke = proxy.invokeSuper(obj, args);
                System.out.println("end.....");
                return invoke;
            }
        });
        Object o1 = enhancer.create();

四、CGLIB动态代理与JDK动态区别

    java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
    而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

    两种方式性能比较:jdk1.6/1.7时,cglib更快;jdk1.8时jdk动态代理速度上来了。 同时,CGLib创建对象慢,对象的运行时调用比较快,适合对单例的代理或者有实例池的代理。

五、AOP中用哪种方式代理:

1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP,也可以强制使用CGLIB实现AOP
2、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值