代理proxy的一点认识

Spring aop 面向切面进行开发,实现的原理就是使用动态代理设计模式,这也是spring框架的一个核心。目标对象不愿意做的事,让代理来实现。
举例:经纪人和艺人的关系,经纪人便是代理,艺人就是目标用户,艺人不想做的(安装设备,舞台等),由经纪人去联系处理,这样的模式就是代理模式。

Jdk:静态代理 动态代理 cglib 生成的动态代理

  • 静态代理的缺点:扩展性差,每次生成只要有不同的目标对象,即使操作的一样,也要重新生成一个代理对象
  • 优点:好理解,代码看起来不复杂

定义一个接口

package com.offcn.test;

public interface Singer {

 public void singing();
 public void dancing();
}

实现接口

package com.offcn.test;

public class WangBaoQiang implements Singer{

    @Override
    public void singing() {
        System.out.println("正在唱歌");
    }

    @Override
    public void dancing() {
        System.out.println("正在跳舞");
    }
}

静态代理

package com.offcn.test;

/**
 *代理对象
 * 首先代理对象也要实现我们的接口
 * 也要调用我们王宝强(目标对象的方法)
 */
public class ProxyWang implements Singer {
    private Singer singer;

    public ProxyWang(Singer singer) {
        this.singer = singer;
    }

    @Override
    public void singing() {
        System.out.println("舞台已经搭建成功");
        singer.singing();
    }

    @Override
    public void dancing() {
        System.out.println("跳舞的舞台已经搭建成功,请开始你的表演");
        singer.dancing();

    }
}

动态代理

package com.offcn.test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * 实现动态代理 jdk
 */
public class ProxyAi implements InvocationHandler {
    //目标对象
    private Object object;

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

    //只要你调用目标对象的方法都会走这个方法
    //第一个参数是你的代理对象,第二个参数是你调用目标对象的方法(通过反射来实现)
    //第三个参数是你调用目标对象的方法里的参数
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object o = null;
        if (method.getName().equals("singing")) {
            System.out.println("搭建舞台成功!");
            o = method.invoke(object, args);
            System.out.println("唱歌结束!");
        } else if (method.getName().equals("dancing")) {
            System.out.println("搭建舞台成功!");
            o = method.invoke(object, args);
            System.out.println("演出结束");

        }
        return o;
    }
}

cglib 生成的动态代理

	package com.offcn.test;

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

import java.lang.reflect.Method;
    //MethodInterceptor 方法拦截器
public class CglibProxy implements MethodInterceptor {

    //实例化目标对象
    private  Object object;
    // 创建代理对象
    public Object getCglibProxy(Object object){
        this.object=object;
        //得到创建代理对象的对象
        Enhancer enhancer = new Enhancer();
        //设置类加载器
        enhancer.setClassLoader(this.object.getClass().getClassLoader());
        //设置其父类
        enhancer.setSuperclass(this.object.getClass());
        //设置回调,只要走下面这个方法都会走回调
        enhancer.setCallback(this);
        //创建代理对象
        return enhancer.create();
    }
        //这个方法就是在你调用目标对象的方法都会执行这个方法
        //第一个参数是代理对象,第二个参数是目标对象的方法,第三个参数是目标对象的方法参数,第四个对象是你的代理对象拦截方法的对象
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        Object ob = method.invoke(object, objects);
        return null;
    }
}

测试类

package com.offcn.test;

import java.lang.reflect.Proxy;

public class Test {
    public static void main(String[] args) {
        //首先实例化的对象是王宝强(也就是我们的目标对象)
        //Singer singer = new WangBaoQiang();

        //实例化代理对象来调用其方法(在调用目标对象的前后做一些相关的操作 )
/*        ProxyWang proxyWang = new ProxyWang(singer);
        proxyWang.singing();*/

        /*-----------------动态代理------------------------*/
        //需要一个目标对象
        //Singer singer = new WangBaoQiang();
        Singer singer = new XueZhiQian();
        //jdk提供了这样一个类,代表代理的意思
        //第一个参数叫做类加载器,第二个参数是目标对象的.class
        //第三个参数也就是代理对象
    /*    Singer singer1 = (Singer) Proxy.newProxyInstance(singer.getClass().getClassLoader(), new Class[]{Singer.class},
                new ProxyAi(singer));
        singer1.singing();*/
        //ProxyAi proxyAi = new ProxyAi(singer);

        //实例化一个cglibProxy 代理对象这个类

        CglibProxy cglibProxy = new CglibProxy();
        Singer singer1 = new WangBaoQiang();
        //这个参数代表我们的目标对象
        Singer singer2 = (Singer) cglibProxy.getCglibProxy(singer1);
        singer2.singing();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值