设计模式-代理模式

一、代理模式基本概述

代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。通俗的来讲代理模式就是我们生活中常见的中介。

二、代理模式的优势

1、解耦

2、功能扩展

三、代理模式的分类

1、静态代理:由程序员创建或由特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。

2、动态代理:在程序运行时,运用反射机制动态创建而成。

四、静态代理和动态代理的区别

静态代理通常只能代理一个类,而动态代理是代理一个接口下的多个实现类

静态代理实现知道要代理的是什么,而动态代理不知道要代理什么东西,只有在运行的时候才知道

五、静态代理代码案列

package com.sheting.reflect.proxy.staticproxy;

import java.util.Date;

//接口
public interface HelloService {

    String echo(String msg);

    Date getTime();
}

package com.sheting.reflect.proxy.staticproxy;

import java.util.Date;

//实现类
public class HelloServiceImpl implements HelloService {
    @Override
    public String echo(String msg) {
        return "echo:" + msg;
    }

    @Override
    public Date getTime() {
        return new Date();
    }
}

package com.sheting.reflect.proxy.staticproxy;

import java.util.Date;

//代理类
public class HelloServiceProxy implements HelloService {
    //表示被代理的HelloService 实例
    private HelloService helloService;

    public HelloServiceProxy(HelloService helloService) {
        this.helloService = helloService;
    }

    public void setHelloServiceProxy(HelloService helloService) {
        this.helloService = helloService;
    }

    @Override
    public String echo(String msg) {
        //预处理
        System.out.println("before calling echo()");
        //调用被代理的HelloService 实例的echo()方法
        String result = helloService.echo(msg);
        //事后处理
        System.out.println("after calling echo()");
        return result;
    }

    @Override
    public Date getTime() {
        //预处理
        System.out.println("before calling getTime()");
        //调用被代理的HelloService 实例的getTime()方法
        Date date = helloService.getTime();
        //事后处理
        System.out.println("after calling getTime()");
        return date;
    }
}


 六、JDK动态代理案列

/**
 * @author: xuWei
 * @create: 2019/12/19
 * 接口
 */
public interface People {
    public void sayHello();
}

/**
 * @program: demo
 * @author: xuWei
 * @create: 2019/12/19
 * @description:实现类
 */
public class PeopleImpl implements People {

    @Override
    public void sayHello() {
        System.out.println("chinesse say hello");
    }
}

/**
 * @program: demo
 * @author: xuWei
 * @create: 2019/12/19
 * @description:代理类
 */
public class PeopleInvocationHandler implements InvocationHandler {

    private Object target;

    public Object getTarget(Object target) {
        this.target = target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("记录日志开始");
        Object invoke = method.invoke(target, args);
        System.out.println("记录日志结束");
        return invoke;
    }
}

八、Cglib动态代理

/**
 * @program: demo
 * @author: xuWei
 * @create: 2019/12/19
 * @description:Cglib动态代理类
 */
public class CglibDynamisProxy implements MethodInterceptor {

    private Object target;

    public Object getInstance(Object target){
        this.target=target;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(this.target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("记录日志开始");
        Object invoke = methodProxy.invokeSuper(o,objects);
        System.out.println("记录日志结束");
        return invoke;
    }
}

九、JDK动态代理和Cglib动态代理的区别?

JDK动态代理利用反射机制实现一个代理接口的匿名类,如果目标对象实现了接口,默认情况下采用JDK代理

Cglib动态代理,将代理对象的class文件加载进来,通过修改字节码生成子类来处理,覆盖其中的方法,因为是继承,所以目标对象的类或方法最好不要声明成final

十、JDK为什么不能针对类生成代理?

由于java的单继承,动态生成的代理类已经继承了Proxy类的,就不能再继承其他的类,所以只能靠实现被代理类的接口的形式,故JDK的动态代理必须有接口。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值