代理模式

静态代理:

优点:

可完成在不修改目标对象的功能前提下,对目标功能扩展.

缺点:

1. 都要实现公共接口

2. 需要创建一个代理类,并且只能代理一个对象

用例:

package designPattern.proxy;

/**
 * @Author Snail
 * @Describe
 * @CreateTime 2019/6/29
 */
public class TestStaticProxy {
    public static void main(String[] args) {
        Static aStatic = new Static();
        //代理对象,把目标对象传给代理对象,建立代理关系
        StaticProxy proxy = new StaticProxy(aStatic);
        proxy.save();//执行的是代理的方法
    }
}
//接口
interface IStatic {
    void save();
}
//目标对象
class Static implements IStatic {
    public void save() {
        System.out.println("----已经保存数据!----");
    }
}
//静态代理对象
class StaticProxy implements IStatic{
    //接收保存目标对象
    private Static target;
    public StaticProxy(Static target){
        this.target=target;
    }

    public void save() {
        System.out.println("开始事务...");
        target.save();//执行目标对象的方法
        System.out.println("提交事务...");
    }
}

JDK动态代理:

目标对象必须有接口,且创建的代理对象也是需要转化成接口类型去执行方法,这个过程制作快,执行慢

package designPattern.proxy;

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

/**
 * @Author Snail
 * @Describe
 * @CreateTime 2019/6/29
 */
public class TestDynamicProxy {
    public static void main(String[] args) {
        //目标对象
        final Dynamic target = new Dynamic();
        //动态创建代理对象
        IDynamic proxy = (IDynamic) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    //被执行几次?------- 看代理对象调用方法几次
                    //代理对象调用接口相应方法 都是调用invoke
                    /*
                     * proxy:是代理对象
                     * method:代表的是目标方法的字节码对象
                     * args:代表是调用目标方法时参数
                     */
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("开始事务...");
                        //反射知识点
                        Object invoke = method.invoke(target, args);//目标对象的相应方法
                        System.out.println("提交事务...");
                        //retrun返回的值给代理对象
                        return invoke;
                    }
                }
        );
        proxy.save();//调用invoke---Method:目标对象的method1方法  args:null  返回值null
        String retMethod = proxy.retMethod("动态代理 ");调用invoke-----Method:目标对象的retMethod方法 args:Object[]{}  返回值
        System.out.println(retMethod);
    }
}

/**
 * 公共接口
 */
interface IDynamic{
    void save();
    String retMethod(String str);
}
/**
 * 目标对象
 */
class Dynamic implements IDynamic{

    @Override
    public void save() {
        System.out.println("保存數據。。。。。");
    }

    @Override
    public String retMethod(String str) {
        return str+"目标对象";
    }
}

CGlib动态代理:

以 继承 来实现,主要解决没有接口类的代理实现。 这个过程制作慢,执行快。

public class TestCGlibProxy {
    public static void main(String[] args) {
        CGlibProxyFactory factory = new CGlibProxyFactory();
        CGlib cGlib = (CGlib) factory.getProxyInstance(new CGlib());
        String str=cGlib.retMethod("Tom");
        System.out.println(str);

    }
}
class CGlibProxyFactory implements MethodInterceptor {

    private Object targetObject;
    //给目标对象创建一个代理对象
    public Object getProxyInstance(Object targetObject){
        this.targetObject = targetObject;
        //1.工具类
        Enhancer enhancer = new Enhancer();
        //2.设置父类
        enhancer.setSuperclass(this.targetObject.getClass());
        //3.设置回调函数
        enhancer.setCallback(this);
        //4.创建子类(代理对象)
        return enhancer.create();
    }
    /**
     * 当代理对象的方法被调用时会调用该方法
     * @param proxy     带来的对象本身
     * @param method    被拦截到的方法
     * @param objects   方法的参数
     * @param methodProxy   方法的代理对象
     */
    @Override
    public Object intercept(Object proxy, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        Object ret = null;

        try {
            System.out.println("sout in cglib proxy ::::before");
            ret = method.invoke(this.targetObject, objects);
            System.out.println("sout in cglib proxy ::::after");
        } catch (Exception e){
            e.printStackTrace();
        }
        return ret;
    }
}
//目标对象    该类由于是使用继承原理实现的,所以类不能用final修饰,类中属性可以
class CGlib{

    public String retMethod(String tom) {
        System.out.println("sout in cglib ");
        return "sout in cglib :"+tom ;
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值