java动态代理

cglib代理

cglib代理主要通过对字节码的操作,为对象引入间接级别,以控制对象的访问。我们知道Java中有一个动态代理也是做这个事情的,那我们为什么不直接使用Java动态代理,而要使用cglib呢?答案是cglib相比于JDK动态代理更加强大,JDK动态代理虽然简单易用,但是其有一个致命缺陷是,只能对接口进行代理。如果要代理的类为一个普通类、没有接口,那么Java动态代理就没法使用了。

pom文件依赖

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>2.2.2</version>
</dependency>

被代理对象

package cn.test.proxy.actor;

/**
 * 目标对象:演员
 */
public class ArtActor {

    /**
     * 基本表演
     */
    public void basicAct(Float money) {
        System.out.println("演员【"+getActorName()+"】收到钱:"+money+",开始基本表演。");
    }

    /**
     * 高难度表演
     */
    public void difficultyAct(Float money) {
        System.out.println("演员【"+getActorName()+"】收到钱:"+money+",开始高难度表演。");
    }

    /**
     * 演员名称
     */
    public String getActorName(){
        return "小花";
    }
}

方法拦截器与代理类测试

package cn.test.proxy.play;

import cn.itheima.proxy.actor.ArtActor;
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 Play {

    public static void main(String[] args) {
      
        /**
         * 版本二:剧组通过经纪人人,找演员表演
         * 实现方式:
         *      第三方的cglib动态代理实现
         *  涉及到的类:
         *       EnHancer
         *  涉及到的方法:
         *      create()
         *  参数:
         *      Class:被代理类的字节码
         *      Callback:如何代理。这里是实现增强的地方。相当于InvocationHandler
         */
        // 创建目标对象(演员)
       final ArtActor actor = new ArtActor();

       // 创建代理对象(经纪人)
        ArtActor actorProxy = (ArtActor)Enhancer.create(
                actor.getClass(),

                new MethodInterceptor() {
                    /**
                     *实现增强功能方法:intercept()。相当于invoke()
                     * 参数:
                     *      proxy:代理对象引用。一般用不到
                     *      method:当前执行的方法对象
                     *      args:当前执行方法的参数列表
                     *      methodProxy:当前方法对象的代理引用。一般用不到
                     */
                    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {

                        // 1.剧组找到经纪人
                        // 1.1.明确表演需求:方法名称
                        String methodName = method.getName();

                        // 1.2.明确出场费用
                        Float money = (Float) args[0];

                        // 2.经纪人联系演员:是基本表演?还是高难度表演?给多少钱?
                        System.out.println("经纪人正在联系演员。");

                        // 2.1.是基本表演吗?基本表演要求5000块
                        Object retV = null;
                        if("basicAct".equals(methodName)){
                            if(money >= 5000){
                                System.out.println("基本表演,剧组钱给到位了。演员收下这个剧本。");
                                // 开始表演
                                retV = method.invoke(actor, money * 4 / 5);
                            }else{
                                System.out.println("剧组只给了:"+money+",钱不到位。演员表示档期太满。");
                            }
                        }

                        // 2.2.是高难度表演吗?高难度表演要求10000块
                        if("difficultyAct".equals(methodName)){
                            if(money >= 10000){
                                System.out.println("高难度表演,剧组钱给到位了。演员收下这个剧本。");
                                retV = method.invoke(actor,money*4/5);
                            }else{
                                System.out.println("剧组只给了:"+money+",钱不到位。演员直接表示拒绝这个剧本。");
                            }
                        }
                        return retV;
                    }
                }
        );

        // 经纪人代理演员,开始表演
        // 基本表演
        actorProxy.basicAct(5000f);

        System.out.println("----------------华丽丽分割线----------------");
        // 高难度表演
        actorProxy.difficultyAct(10000f);
    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值