代理模式之动态代理的实现——CGLib

CGLib实现动态代理


先记住一句话——CGLib代理实现的原理是子类增强了父类

使用JDK的Proxy实现代理,要求目标类与代理类实现相同的接口。若目标类不存在接口,则无法使用该方式实现。

但对于无接口的类,要为其创建动态代理,就要使用CGLIB来实现。CGLIB代理的生成原理是生成目标类的子类,而子类是增强过的,这个子类对象就是代理对象。所以,使用CGLIB生成动态代理,要求目标类必须能够被继承,即不能是final的类。

使用CGLIB创建代理步骤

1)、导入CGLIB的Jar包
cglib-full.jar

jar的获取请参考CGLib所需jar与源码下载教程

2)、定义目标类。(注意不用实现任何接口)
package com.hk.service;
/**
 *  目标类
 * @author 浪丶荡
 *
 */
public class SomeService{

    public String Litigate() {
        return "自己打官司,输了";
    }

    public String eat() {
        return "自己吃饭";
    }

}

3)、创建代理类的工厂
package com.hk.factory;

import java.lang.reflect.Method;

import com.hk.service.SomeService;

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

/**
 *  创建代理类的工厂 该类要实现MethodInterceptor接口。
 *  该类中完成三样工作
 * (1)声明目标类的成员变量,并创建以目标类对象为参数的构造器。用于接收目标对象
 * (2)定义代理的生成方法,用于创建代理对象。方法名是任意的。代理对象即目标类的子类 
 * (3)定义回调接口方法。对目标类的增强这在这里完成
 * 
 * @author 浪丶荡
 * 
 */
public class CGLibFactory implements MethodInterceptor {
    // 声明目标类的成员变量
    private SomeService target;

    public CGLibFactory() {
    }

    // 创建以目标类对象为参数的构造器,用于接收目标对象
    public CGLibFactory(SomeService someService) {
        this.target = someService;
    }

    // 定义代理的生成方法,用于创建代理对象
    public SomeService myCGLibCreator() {
        Enhancer enhancer = new Enhancer();
        // 为代理对象设置父类,即指定目标类
        enhancer.setSuperclass(SomeService.class);
        /**
         * 设置回调接口对象 注意,只所以在setCallback()方法中可以写上this,
         * 是因为MethodIntecepter接口继承自Callback,是其子接口
         */
        enhancer.setCallback(this);
        return (SomeService) enhancer.create();// create用以生成CGLib代理对象
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args,
            MethodProxy proxy) throws Throwable {
        if (method.toString().contains("eat")) {// 吃饭就不用律师代劳了,自己来
            return (String) method.invoke(target, args);// 反射,调用目标类的方法;
        }
        return "律师打官司,赢了";
    }

}

测试类

package com.hk.test;

import com.hk.factory.CGLibFactory;
import com.hk.service.SomeService;
public class MyTest {
    public static void main(String[] args) {
        //有money人张三
        SomeService zhangsan = new SomeService();
        //屌丝李四
        SomeService lisi = new SomeService();
        //张三请人打官司
        SomeService someService = new CGLibFactory(zhangsan).myCGLibCreator();
        System.out.println("zhangsan"+someService.Litigate()+"-----"+someService.eat());
        //苦逼的李四自己打官司,自己吃饭
        System.out.println("lisi"+lisi.Litigate()+"-----"+lisi.eat());
    }
}

结果

zhangsan律师打官司,赢了-----自己吃饭
lisi自己打官司,输了-----自己吃饭
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值