代理模式 – cglib代理

代理模式 – cglib代理

 目录

 cglib代理

 例子-常规

代码:

问候 Greet

问候实现 GreetIml

商店 Shop

商店实现 ShopImpl

cglib代理 CGLibProxy

测试:,

结果:

例子-单例模式

代码:

cglli代理 CGLibProxySingle

测试:

结果:

总结:


 cglib代理

在使用的是静态代理动态代理都需要目标对象是一个实现了接口的目标对象,当目标对象可能只是一个单独的对象,并没有实现任何的接口,那如何进行代理? 需要使用cglib代理

 

Cglib代理是什么?

   Cglib代理,也叫做子类代理,它是在内存中构件一个子类对象,从而实现对目标对象的功能拓展。 cglib包的底层是通过使用一个小而快的字节码处理框架ASM来转换字节码并生成新的类,不鼓励直接只使用ASM,因为它要求你必须对JVM内部结构,包括class文件的格式和指令集都很熟悉。

 

如何实现呢?

   在Java中要想实现cglib代理机制,需要org.springframework.cglib.proxy.MethodInterceptor接口和 org.springframework.cglib.proxy.Enhancer 类的支持

 

 例子-常规

 

代码:

问候 Greet

public interface Greet {
    void say(String name);
}

 

问候实现 GreetIml

public class GreetImpl implements Greet {
    @Override
    public void say(String name) {
        System.out.println("Hi! " + name);
    }
}

 

商店 Shop

public interface Shop {
    void sell(String wares);
}

 

商店实现 ShopImpl

public class ShopImpl implements Shop {
    @Override
    public void sell(String foodName) {
        System.out.println("sell the " + foodName);
    }
}

 

cglib代理 CGLibProxy

public class CGLibProxy implements MethodInterceptor {

    public <T> T getProxy(Class<T> cls) {
        return (T) Enhancer.create(cls, (Callback) this);
    }

    // CGLib 给我们提供的是方法级别的代理,也可以理解为为对方法的拦截
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        before();
        Object result = methodProxy.invokeSuper(obj, args);
        after();
        return result;
    }

    private void before() {
        System.out.println("Before");
    }

    private void after() {
        System.out.println("After");
    }
}

在cglib代理类中,实现MethodInterceptor 的接口,调用 methodProxy.invokeSuper(obj, args)

 

测试:,

public   class TestCglib {
    public static void main(String[] args) throws Exception {
        CGLibProxy cgLibProxy = new CGLibProxy();
        System.out.println("========== greet proxy ==========");
        Greet greetProxy = cgLibProxy.getProxy(GreetImpl.class);
        greetProxy.say("cglib");

        System.out.println("========== shop proxy ==========");
        Shop shopProxy = cgLibProxy.getProxy(ShopImpl.class);
        shopProxy.sell(" potato chips");
    }
}

 

结果:

========== greet proxy ==========

Before

Hi! cglib

After

========== shop proxy ==========

Before

sell the  potato chips

After

 

例子-单例模式

 

代码:

cglli代理 CGLibProxySingle

public class CGLibProxySingle implements MethodInterceptor {
    private static class CGLibProxySingleHandler {
        private static CGLibProxySingle staticInnerSingle = new CGLibProxySingle();
    };

    private CGLibProxySingle() {
    }

    public static CGLibProxySingle getInstance() {
        return CGLibProxySingleHandler.staticInnerSingle;
    }

    public <T> T getProxy(Class<T> cls) {
        return (T) Enhancer.create(cls, (Callback) this);
    }

    // CGLib 给我们提供的是方法级别的代理,也可以理解为为对方法的拦截
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        before();
        Object result = methodProxy.invokeSuper(obj, args);
        after();
        return result;
    }

    private void before() {
        System.out.println("Before");
    }

    private void after() {
        System.out.println("After");
    }
}

 结合单例模式的静态内部类的引用

测试:

public class TestCglibSingle {
    public static void main(String[] args) throws Exception {
        System.out.println("========== greet proxy ==========");
        Greet greetProxy = CGLibProxySingle.getInstance().getProxy(GreetImpl.class);
        greetProxy.say("cglib singleton");

        System.out.println("========== shop proxy ==========");
        Shop shopProxy = CGLibProxySingle.getInstance().getProxy(ShopImpl.class);
        shopProxy.sell("fried chicken");
    }
}

 

结果:

========== greet proxy ==========

Before

Hi! cglib singleton

After

========== shop proxy ==========

Before

sell the fried chicken

After

 

总结:

  当目标对象可能只是一个单独的对象,并没有实现任何的接口,这个时候需要cglib代理方式,即使用目标对象子类的方式实现代理.

动态代理和cgli代理进行比较:

1,对象不同:

      Java动态代理只能够对接口进行代理,不能对普通的类进行代理(因为所有生成的代理类的父类为Proxy,Java类继承机制不允许多重继承);

      CGLIB能够代理普通类;

2,实现方式不同:

      Java动态代理使用Java原生的反射API进行操作,在生成类上比较高效;

      CGLIB使用ASM框架直接对字节码进行操作,在类的执行过程中比较高效

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天狼1222

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值