java代理模式(静态代理和动态代理)

1 概述

  • 把核心功能和辅助功能分开
  • 将核心功能与辅助功能(事务、日志、性能监控代码)分离,达到核心业务功能更纯粹、辅助业务功能可复用。

2 静态代理

  • 通过代理类的对象,为原始类的对象(目标类的对象)添加辅助功能,更容易更换代理实现类、利于维护。
  • 代理和被代理类之间实现相同的接口,代理调用被代理类中的方法,在此基础上添加赋值的功能
ChuZu接口
package com.sw.staticProxy;

public interface ChuZu {
    Double zuFang(Double money);
}
FangDong
package com.sw.staticProxy;

public class FangDong implements ChuZu {

    @Override
    public Double zuFang(Double money) {
//        System.out.println("房东发布租房广告...");
//        System.out.println("房东带看房子...");
//        System.out.println("房东签订合同...");
        System.out.println("房东收取租金..." + money);
//        System.out.println("房东提供服务...");
        return money*0.95;
    }
}
ZhongJie
package com.sw.staticProxy;

public class ZhongJie implements ChuZu {

    @Override
    public Double zuFang(Double money) {
        FangDong fangDong = new FangDong();
        System.out.println("中介发布租房广告...");
        System.out.println("中介带看房子...");
        System.out.println("中介组织租客和房东签订合同...");
        fangDong.zuFang(money*0.9);
        System.out.println("中介提供服务...");
        return money*0.9;
    }

}
测试
package com.sw;

import com.sw.staticProxy.FangDong;
import com.sw.staticProxy.ZhongJie;
import org.junit.Test;

public class TestStaticChuZu {

    @Test
    public void chuZu01(){
        FangDong fangDong = new FangDong();
        Double ret = fangDong.zuFang(2000.0);
    }

    @Test
    public void chuZu02(){
        ZhongJie zhongJie = new ZhongJie();
        Double ret = zhongJie.zuFang(2000.0);
    }
}

3 JDK动态代理

  • 基于接口
  • 代理对象转换成被代理对象实现的接口的类型
  • 在处理程序方法中调用被代理对象的核心业务方法,添加辅助功能
ChuZu
package com.sw.jdkProxy;

/**
 * 公共的接口
 */
public interface ChuZu {
    Double chuZu(Double money);
}
FangDong
package com.sw.jdkProxy;

/**
 * 房东
 *  出租房屋
 */
public class FangDong implements ChuZu {

    @Override
    public Double chuZu(Double money) {
        System.out.println("房东出租房屋");
        return money;
    }

}
动态代理
package com.sw.jdkProxy;

import org.junit.Test;

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

public class TestJdk {

    @Test
    public void getZu(){
        FangDong fangDong = new FangDong();

        /**
         * ClassLoader loader,      被代理对象的类加载器
         * Class<?>[] interfaces,   被代理对象实现的接口s
         * InvocationHandler h)     代理要干的事
         */
        ChuZu proxyInstance = (ChuZu) Proxy.newProxyInstance(
                fangDong.getClass().getClassLoader(),
                fangDong.getClass().getInterfaces(),
                new InvocationHandler() {

                    /**
                     * @param proxy     代理对象
                     * @param method    接口中的方法--核心业务代码
                     * @param args      方法传入的参数
                     * @return
                     * @throws Throwable
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                        System.out.println("中介发布广告...");
                        System.out.println("中介带看房子...");
                        System.out.println("中介组织签合同...");

                        // 核心业务
                        Double ret = (Double) args[0] * 0.9;
                        Object object = method.invoke(fangDong, ret);

                        System.out.println("中介提供服务...");

                        return object;
                    }
                }
        );

        Double ret = proxyInstance.chuZu(2000.0);
        System.out.println(ret);
    }
}

4 CGlib动态代理

  • 基于继承(可以指定为默认)
  • 需要使用CGLIB依赖
FangDong
package com.sw.jdkProxy;

/**
 * 房东
 *  出租房屋
 */
public class FangDong {

    public Double chuZu(Double money) {
        System.out.println("房东出租房屋");
        return money;
    }

}
代理对象
package com.sw.cglibProxy;

import com.sw.jdkProxy.FangDong;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.junit.Test;

import java.lang.reflect.Method;

public class TestCGlib {

    @Test
    public void getCG(){
        FangDong fangDong = new FangDong();

        FangDong proxyInstance = (FangDong) Enhancer.create(
                FangDong.class,
                new MethodInterceptor() {
                    @Override
                    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {

                        System.out.println("中介发布广告..");
                        System.out.println("中介带看房子..");
                        System.out.println("中介组织签合同..");

                        Double ret = (Double) args[0] * 0.9;
                        Object object = method.invoke(fangDong, ret);

                        System.out.println("中介提供服务..");
                        return object;
                    }
                }
        );
        Double ret = proxyInstance.chuZu(2000.0);
        System.out.println(ret);
    }
}

5 自定义创建代理对象的方法

    public <T> T getMapper(Class<T> clazz){
        T proxyInstance = (T) Enhancer.create(
               clazz,
                new MethodInterceptor() {
                    @Override
                    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {

                        System.out.println("中介发布广告..");
                        System.out.println("中介带看房子..");
                        System.out.println("中介组织签合同..");

                        Double ret = (Double) args[0] * 0.9;
                        Object object = method.invoke(clazz.newInstance(), ret);

                        System.out.println("中介提供服务..");
                        return object;
                    }
                }
        );
        return proxyInstance;
    }
    @Test
    public void getProxy(){
        FangDong proxy = getMapper(FangDong.class);
        Double ret = proxy.chuZu(3000.0);
        System.out.println(ret);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你读书了吗?

生活不易,赏点饭吃

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值