静态-动态代理自我总结

一、代理

代理是一种设计模式,简单来说就是老板需要对接很多客户,这时候秘书(代理)出现了,可以帮老板解决本来不属于老板干的活。

根据字节码进行分类:

静态代理:提前就写好代理类,程序运行前就有字节码文件。

动态代理:程序运行前没有字节码文件,而是在运行时通过反射动态的生成代理对象字节码

二、静态代理

也就是在运行前已经定义好了代理类。直接编译运行即可

优点:没有侵入原代码!

缺点

  • 不复用,一个代理类只能代理一个类
  • 代码固化,代理类直接写好了,不能动态的增强代码

三、动态代理

动态代理也就是在使用时动态的创建代理对象。


实现方式:

1,JDK代理

由jdk提供的技术,基于反射,前提是代理类需实现与目标类一样的接口,这样代理类就有与接口一样的方法了。

书写顺序

  1. 创建一个方法拦截控制器类,该类实现了InvocationHandler接口,并重写方法invoke,该方法是代理方法,有什么需要增强的代码可以写在里面,是真正执行代理方法的类
  2. 调用 Proxy.newProxyInstance 方法,其中:

    形参1:目标类的类加载器
    形参2:目标类实现的所有接口类数组
    形参3:顺序1创建的方法拦截控制器类对象
    返回值:代理对象

  3. 使用代理对象调用所需的方法即可

代码:引用大佬的模版

public class JDKProxyFactory implements InvocationHandler {

    //需要被代理的对象
    private Object object;

    public JDKProxyFactory(Object object) {
        this.object = object;
    }

    @SuppressWarnings("unchecked")
    public <T> T getProxy(){
        return (T) Proxy.newProxyInstance(
                Thread.currentThread().getContextClassLoader(),//当前线程的上下文ClassLoader
                object.getClass().getInterfaces(), //代理需要实现的接口
                this); // 处理器自身
    }
	
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
		//进行方法匹配,调用对应方法名的方法
        if ("loadVideo".equals(method.getName())) {
            result=method.invoke(object, args);
        }

        if ("playVideo".equals(method.getName())) {
            System.out.println("前置增强");
            result=method.invoke(object, args);
            System.out.println("后置增强");
        }
        return result;
    }
}

2,CGLIB代理   

使用JDK创建代理有一个限制,它只能为接口创建代理实例.这一点可以从Proxy的接口方法 newProxyInstance(ClassLoader loader,Class [] interfaces,InvocarionHandler h)中看的很清楚对于没有通过接口定义业务方法的类,如何动态创建代理实例呢? JDK动态代理技术显然已经黔驴技穷,CGLib作为一个替代者,填补了这一空缺。GCLib采用底层的字节码技术,可以为一个类创建子类,在子类中采用方法拦截的技术拦截所有父类方法的调用并顺势志入横切逻辑.

CGLib需要引入jar包,即cglib.jar

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.2.4</versi
<dependency>

创建CGLib代理器:

public class CglibProxy implements MethodInterceptor {
 
    private Enhancer enhancer = new Enhancer();
 
    // 切面类(这里指事务类)
    private MyTransaction transaction;
 
    public CglibProxy(MyTransaction transaction) {
        this.transaction=transaction;
    }
 
    // 设置被代理对象
    public Object getProxy(Class clazz) {
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return enhancer.create();
    }
 
    public Object intercept(Object obj, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        transaction.before();
        Object invoke = methodProxy.invokeSuper(obj, objects);
        transaction.after();
        return invoke;
    }
}

关于代理模式,可以理解为为了减少代码量,实现代码的复用,把一些相同的代码提取出去。通过代理来实现,而代理实现一般就用动态代理,动态代理使用时,根据有无接口实现来选择JDK动态代理或者CGLib动态代理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值