代理模式

时间:2020-08-14 23:34:12   收藏:0   阅读:86

11、代理

场景:

1、租房:包括房东(真实对象),中介(代理对象),客户(被代理对象)

技术分享图片

静态代理

实例测试静态代理模式

技术分享图片

Why?

UserDao

public interface UserDao {

    //增
    int add();

    //删
    int delete();

    //查
    List<User> select();

    //改
    int update();

}

UserDaoImpl

public class UserDaoImpl implements UserDao {
    @Override
    public int add() {
        System.out.println("增");
        return 0;
    }

    @Override
    public int delete() {
        System.out.println("删");
        return 0;
    }

    @Override
    public List<User> select() {
        System.out.println("查");
        return null;
    }

    @Override
    public int update() {
        System.out.println("改");
        return 0;
    }
}

StaticProxy

public class StaticProxy implements UserDao {

    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public int add() {
        log("正在执行增加操作");
        userDao.add();
        return 0;
    }

    @Override
    public int delete() {
        log("正在执行删除操作");
        userDao.delete();
        return 0;
    }

    @Override
    public List<User> select() {
        log("正在执行查询操作");
        userDao.select();
        return null;
    }

    @Override
    public int update() {
        log("正在执行修改操作");
        userDao.update();
        return 0;
    }

    //需求:切入一段日志
    private static void log(String msg){
        System.out.println("[DEBUG]"+msg);
    }

    public void myMethod(){
        System.out.println("这是我代理类特有的方法");
    }
}

Test

@Test
public void test(){
    //真实对象需要做的事情
    UserDao userDao = new UserDaoImpl();

    //需要一个代理对象
    StaticProxy proxy = new StaticProxy();

    //代理对象去代理真实类【set方法】
    proxy.setUserDao(userDao);

    //执行被代理对象需要执行的操作
    proxy.add();

    //代理对象还可以自己做一些额外的操作
    proxy.myMethod();
}

好处:

不用修改自身原来的代码而动态实现代码的切入;

真实对象只需负责主要的业务,不用关心一些公共的业务,实现的业务的分工。

坏处:

静态代理一个真实对象就会产生一个代理对象,代码量增加,效率变低。

动态代理

动态代理的方式:

  1. 基于接口:JDK动态代理
  2. 基于类:cglib
  3. java字节码:javassist

动态代理需要了解2个类:

技术分享图片

DynamicProxy

/**
 * 动态代理的实现
 */
//用来创建代理对象,并执行代理程序
public class DynamicProxy implements InvocationHandler {

    //代理类所需要代理的真实对象
    private Object object;

    public void setObject(Object object) {
        this.object = object;
    }

    //获取代理对象
    public Object getProxy(){
        /**
         * 参数一:生成代理对象的类加载器
         * 参数二:代理类所要代理的接口
         * 参数三:指实现InvocationHandler的类
         */
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),object.getClass().getInterfaces(),this);
    }


    //代理对象处理方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //使用代理类method去执行,参数一指的就是所需要代理的真实对象
        Object invoke = method.invoke(object, args);
        return invoke;
    }
}

Test

@Test
public void test1(){
    //真实对象所需要执行的操作
    UserDao user = new UserDaoImpl();

    //创建代理对象处理程序
    DynamicProxy proxy = new DynamicProxy();

    //设置所要代理的真实对象
    proxy.setObject(user);

    //创建代理对象
    UserDao proxy1 = (UserDao) proxy.getProxy();

    //执行
    proxy1.add();

}

总结:静态代理和动态代理的区别?

静态代理:

? 一个类只能创建一个代理对象;

? 代理对象需要程序员自己手动创建;

动态代理

? 可研通过JDK原生接口,或者cglib包动态为所有类创建代理对象;

? 是动态创建的,不用自己手动创建;

原文:https://www.cnblogs.com/IT_CH/p/13506866.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!