代理模式

什么是代理模式?

1.1 代理模式就是给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。
通常来说,我们在一个业务实现类中,我们需要去做一件事情,但是这件事情,我们不能直接去做,这个时候,我们就会委托一个第三方来帮我 干这件事情。这种模式就叫做代理模式。
代理模式由代理者以及被代理者二者构成,我们的代理者会帮我去完成一部分事情,但是最终的执行动 作,还是由我们被代理者去完成。

1.2代理模式常用场景:
拦截器,日志监听,无侵入式功能增强,AOP实现

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

静态代理

目标类与代理类继承同一个类或者实现同一个接口,使用时通过代理调用目标类的方法。
静态代理实现方式
(1)被代理者是固定的,代理者持有被代理者的句柄(引用),帮被代理者去完成一些事情。
(2)静态代理通常可以用两种方式来实现。
第一种,直接持有被代理类(被代理者)的句柄,实现代理方法,增强逻辑 。
第二种,定义一个接口或者抽象类,共同继承类或者接口,实现被代理的方法,在逻辑增强后再交由被代理者执行。

第一种:
被代理类SuperStar.java

package staticproxy;
public class SuperStar
{
    public void moveShow()
    {
        System.out.println("我在演戏.........");
    }
}

代理类:SuperStarProxy.java

package staticproxy;

public class SuperStarProxy
{
     private SuperStar superStar;

    public SuperStarProxy(SuperStar superStar)
    {
        this.superStar = superStar;
    }

    public void moveShow()
    {
        System.out.println("导演XXX. ,给我们superStar排戏........");
        System.out.println("导演:OK,让她来.......");
        System.out.println("经理人:导演让你去试戏.......");
        this.superStar.moveShow();
        System.out.println("XXX,一炮而红.........");
    }
}

测试类ProxyTest

import staticproxy.SuperStar;
import staticproxy.SuperStarProxy;
import java.lang.reflect.Proxy;

public class ProxyTest
{
    public static void main(String[] args) {
     //静态代理
        SuperStarProxy superStarProxy = new SuperStarProxy(new SuperStar());
        superStarProxy.moveShow();
    }
}

第二种:
创建一个接口,代理类与被代理类都继承接口
接口:SuperStar0213

package staticproxy;

public interface SuperStar0213 {
    public  void  moveShw();
}

被代理类:SuperStar

package staticproxy;

public class SuperStar implements SuperStar0213
{
    public void moveShw() {
        System.out.println("我在演戏.........");
    }
}

代理类:SuperStarProxy

package staticproxy;

public class SuperStarProxy implements SuperStar0213
{
     private SuperStar superStar;
    public SuperStarProxy(SuperStar superStar)
    {
        this.superStar = superStar;
    }
    public void moveShw() {
        System.out.println("导演XXX. ,给我们superStar排戏........");
        System.out.println("导演:OK,让她来.......");
        System.out.println("经理人:导演让你去试戏.......");
        this.superStar.moveShw();
        System.out.println("XXX,一炮而红.........");
    }
}

运行结果
在这里插入图片描述

动态代理

动态代理实现方式
被代理者是一个不固定的对象。可能是一个抽象,在代理之前所有的代码都是未知的。利用反射和字节码 技术在运行期间创建代理对象。

JDK动态代理
基于接口实现 被代理者需要实现接口。
JDK动态代理通过反射类Proxy以及InvocationHandler回调接口实现,代理者实现InvocationHandler,在Invoke方法中实现切面进行逻辑增强 。
CGlib 动态代理
对于没有接口的类,CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。
JDK动态代理与CGLib动态代理均是实现Spring AOP的基础。

1.jdk动态代理
定义接口:JDKSuperStar

package jdkdyncproxy;
public interface JDKSuperStar
{
    public void moveShow();
}

被代理类:

package jdkdyncproxy;
public class Yangmi implements JDKSuperStar
{
    public void moveShow()
    {
        System.out.println("我在快乐的演戏..");
    }
}

代理类:JDKProxyHandler

package jdkdyncproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class JDKProxyHandler implements InvocationHandler
{
    private Object superStar ;
    public JDKProxyHandler(Object obj)
    {
        this.superStar = obj;
    }
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    {
  //  Object proxy:要代理的动态代理类--动态生成的
  // Method method:动态代理类所有的实现方法
 //  Object[] args :传的参数
       Object proxyObj =  method.invoke(this.superStar,args);
        return proxyObj;
    }
}

测试类:


/*import cglibproxy.CGProxyHandle;
import cglibproxy.Damimi;*/
import jdkdyncproxy.JDKProxyHandler;
import jdkdyncproxy.JDKSuperStar;
import jdkdyncproxy.Yangmi;
import staticproxy.SuperStar;
import staticproxy.SuperStarProxy;

import java.lang.reflect.Proxy;

public class ProxyTest
{
    public static void main(String[] args) {
        //jdk动态代理
      Yangmi yangmi = new Yangmi();
        JDKProxyHandler jdkProxyHandler = new JDKProxyHandler(yangmi);
        JDKSuperStar jdkSuperStar = (JDKSuperStar)Proxy.newProxyInstance(yangmi.getClass().getClassLoader(),yangmi.getClass().getInterfaces(),jdkProxyHandler);
        jdkSuperStar.moveShow();
    }
}


在这里插入图片描述
若要再代理其他的类,是需要增加相应的实体类,和接口就可以了。

Cglib动态代理

huahua.java

package cglibproxy;

public class huahua
{
    public void moveShow()
    {
        System.out.println("我在快乐的演戏....");
    }
}

CGProxyHandle .java

package cglibproxy;

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

import java.lang.reflect.Method;

public class CGProxyHandle implements MethodInterceptor
{

    public Object getProxy(Class c)
    {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(c);
        enhancer.setCallback((Callback) this);
        return enhancer.create();

    }

    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable
    {
       Object proxInst =  methodProxy.invokeSuper(o,objects);
        return proxInst;
    }
}

测试
ProxyTest.java

import cglibproxy.CGProxyHandle;
import cglibproxy.Damimi;

import java.lang.reflect.Proxy;

public class ProxyTest
{
    public static void main(String[] args) {
        //cglib动态代理
        CGProxyHandle cgProxyHandle = new CGProxyHandle();
        Damimi damimi = (Damimi) cgProxyHandle.getProxy(Damimi.class);
        damimi.moveShow();
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值