代理模式

代理模式是一种结构性模式

结构性模式是解决类或对象组合在一起的经典结构

结构性模式包括:代理模式,桥接模式,装饰者模式,适配器模式,门面模式,组合模式,享元模式

代理模式的原理:在不改变原始类的情况下,通过引入原始类(代理类)的情况下,对原始类附加新的功能。

代理模式又分为静态代理和动态代理

静态代理:程序员手动创建,在程序运行前,已经存在代理类的字节码文件

动态代理:程序运行过程中通过反射创建。

静态代理通过继承或者实现接口的方式,对函数方法进行增强。

缺点:为每一个服务都需要创建一个代理类,如果服务特别多,不利于管理

动态代理:

如果被代理类有接口,使用jdk的动态代理

如果被代理的类没有实现接口,且类没有被final 修饰使用cglib的动态代理。

jdk 动态代理的实现

/**
 * 被代理类实现的接口
 * */
public interface Subject {
    /** 被代理类要执行的方法 */
    void buyHouse();
}
/**
 * @Description: 被代理类

 * @Date: 2020/5/12 17:59
 * @Author: fuguowen
 * @Return 
 * @Throws 
 */
public class RealSubject implements Subject {
    /** 目标方法 */
    public void buyHouse() {
        System.out.println("我会买房子");
    }
}
/**
 * @Description: 代理类  实现InvocationHandle 接口
 *  重写invoke 方法
 * 为什么要实现InvocationHandle 接口  Proxy.newProxyInstance()的第三个参数是一个InvocationHandler接口
 * @Date: 2020/5/12 17:59
 * @Author: fuguowen
 * @Return 
 * @Throws 
 */
public class DynamicProxyHandler implements InvocationHandler {

    private Object object;

    public DynamicProxyHandler(final Object object) {
        this.object = object;
    }


    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("我会找房源");
        Object result = method.invoke(object, args);
        return result;
    }
}
/**
 * @Description: JDK 动态代理类的测试

 * @Date: 2020/5/12 18:19
 * @Author: fuguowen
 * @Return 
 * @Throws 
 */
public class MainClass {
    public static void main(String[] args) {
        /** 创建被代理类 */
        Subject subject = new RealSubject();
        /**
         * ClassLoader loader:指定当前目标对象使用的类加载器,获取加载器的方法是固定的
         * Class<?>[] interfaces:指定目标对象实现的接口的类型,使用泛型方式确认类型
         * InvocationHandler:指定动态处理器,执行目标对象的方法时,会触发事件处理器的方法
         * 找到被代理类的类加载器,被代理类实现的接口,代理类
         */
        Subject proxySubject = (Subject) Proxy.newProxyInstance(Subject.class.getClassLoader(),
                new Class[]{Subject.class},
                new DynamicProxyHandler(subject));
        /** 执行被代理类对应的方法 */
        proxySubject.buyHouse();
    }

}

cglib的动态代理  

CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。

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

import java.lang.reflect.Method;

/**
 * @Description: cglib 动态代理 代理类
 * @Author: Ling.D.S
 * @Date: Created in 2018/11/14 18:36
 */
public class CglibProxy implements MethodInterceptor {
    private Object target;//业务类对象,供代理方法中进行真正的业务方法调用

    //相当于JDK动态代理中的绑定
    public Object getInstance(Object target) {
        this.target = target;  //给业务对象赋值
        Enhancer enhancer = new Enhancer(); //创建加强器,用来创建动态代理类
        enhancer.setSuperclass(this.target.getClass());  //为加强器指定要代理的业务类(即:为下面生成的代理类指定父类)
        //设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实现intercept()方法进行拦
        enhancer.setCallback(this);
        // 创建动态代理类对象并返回
        return enhancer.create();
    }

    // 实现回调方法
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("我会找房源");
        proxy.invokeSuper(obj, args); //调用业务类(父类中)的方法
        return null;
    }
/**
     * @Description: cglib 动态代理类的单元测试
    
     * @Date: 2020/5/12 18:22
     * @Author: fuguowen
     * @Return 
     * @Throws 
     */
    public static void main(String[] args) {
        /** 创建被代理类 */
        RealSubject realSubject = new RealSubject();

        CglibProxy cglibProxy = new CglibProxy();
        RealSubject realSubjectProxy =
                (RealSubject) cglibProxy.getInstance(realSubject);
        realSubjectProxy.buyHouse();
    }

参考:

1. https://blog.csdn.net/kbh528202/article/details/84103931

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值