设计模式学习笔记三十四、代理模式Cglib动态代理代码实现

一、介绍
1、静态代理和JDK代理模式都要求目标是实现一个接口,但是有时候对象只是一个单独的对象,并没有实现任何的接口,这个时候可使用目标对象子类来实现代理=>Cglib代理归属到动态代理。
2、Cglib代理也叫作子类代理,它是在内存中构建一个子类对象,从而实现对目标对象功能扩展。
3、Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展java类与实现java接口,它广泛的被许多AOP的框架使用,例如Spring AOP ,实现方法拦截
4、在AOP编程中如何选择代理模式:
1)目标对象需要实现接口,用JDK代理
2)目标对象不需要实现接口,用Cglib代理
5、Cglib包的底层是通过使用字节码处理框架ASM来转换字节码并生成新的类
在这里插入图片描述

二、注意事项
1、引入cglib的jar文件
2、在内存中动态构建子类,注意代理的类不能为final
3、目标对象的方法如果为final/static,那么就不会被拦截,即不会执行目标对象额外的业务方法。
三、代码

package com.hao.demo.design.cglib;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * @author haoxiansheng
 * @date 2020-05-20
 */
public class ProxyFactory implements MethodInterceptor {

    // 维护一个目标对象
    private Object target;

    // 传入一个被代理的对象
    public ProxyFactory(Object target) {
        this.target = target;
    }

    // 返回一个代理对象,是target 对象的代理对象
    public Object getProxyInstance() {
        // 1、创建一个工具类
        Enhancer enhancer = new Enhancer();
        // 2、设置父类
        enhancer.setSuperclass(target.getClass());
        // 3、设置回调函数
        enhancer.setCallback(this);

        // 4、创建
        return enhancer.create();
    }

    // 重写intercept 方法,会调用目标对象的方法
    @Override
    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("Cglib代理模式开始");
        Object returnValue = method.invoke(target, args);
        System.out.println("Cglib代理模式 --提交");
        return returnValue;
    }
}

package com.hao.demo.design.cglib;

/**
 * @author
 * @date 2020-05-20
 */
public class TeacherDAO {
    public void teach() {
        System.out.println("我是cglib代理,不需要实现接口");
    }
}
package com.hao.demo.design.cglib;

/**
 * @author
 * @date 2020-05-20
 */
public class Client {
    public static void main(String[] args) {
        // 创建对象
        TeacherDAO teacherDAO = new TeacherDAO();
        // 获取到目标对象, 并且传递给目标对象
        TeacherDAO proxyInstance = (TeacherDAO) new ProxyFactory(teacherDAO).getProxyInstance();
        // 执行代理对象的方法,触发interceptor 方法 从而实现对目标对象的调用
        proxyInstance.teach();
    }
}


四、代理模式的变体(Proxy)
1、防火墙代理
内网通过代理穿透防火墙,实现对公网的访问。
2、缓冲代理
比如:当请求图片文件等资源,先到缓冲代理取,如果取到资源则ok,如果取不到资源,再到公网或者数据库取,然后缓冲。
3、远程代理
远程对象的本地代表。通过它可以把远程对象当本地对象来调用。远程代理通过网络和真正的远程对象沟通信息。
4、同步代理:主要使用再多线程编程中,完成多线程同步工作。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值