静态代理与动态代理

代理:就是让代理角色帮助真实角色完成一件事情

静态代理

                代理角色和真实角色都需要实现同一个接口

                特点:代理类和目标类在代码中是确定的

                        可以在不修改目标对象功能的前提下,对目标进行扩展.

                缺点:不够灵活

动态代理

                也叫jdk代理或接口代理,是在程序执行的过程中,通过反射产生的代理对象

                JDK动态代理特点:基于接口实现

                                             代理对象的生成是利用JDK的API动态的在内存中构建代理对象

JDK实现代理只需要使用newProxyInstance方法,该方法需要三个参数,语法格式如下:

public static Object newProxyInstance(ClassLoader loader,Class<?>[ ] interfaces,InvocationHandler h)

注意该方法在Proxy类中是静态方法,且接受的三个参数说明分别为:

ClassLoader loader:实现的接口的类加载器

Class<?> [ ] interfaces:基于接口的字节码文件对象数组

InvocationHandler h:是接口InvocationHandler:代理的处理程序,执行目标对象的方法时,把当前执行目标对象的方法作为参数传入

实例介绍静态代理与动态代理

静态代理

定义一个结婚的接口

interface Marry{
    void marry();
}

每个人(真实角色)都要结婚,实现Marry接口

Class Person implements Marry{    //真实角色
    public void marry();
    System.out.println("结婚是一件开心的事情");
}

婚庆公司--代理角色,帮助人完成结婚这件事

class WeddingCompany implements Marry{
    //声明一个接口Marry类型变量
      private Marry marry;
      public WeddingCompany(Marry marry){        //形式参数是一个借口,需要接口子实现类对象
            this.marry=marry;
}
      public void marry(){
    //代理角色需要帮助真实角色完成结婚这件事
        System.out.println("结婚前,需要布置婚礼现场");
        mary.mary();
        System.out.println("婚礼后,需要支付尾款");
    }
}

测试代码

public class StaticProxyTest{
    public static void main(String [] args){
        //使用静态代理
        Person person = new Person();
        WeddingCompany weddingCompany = new WeddingCompany(person);
        weddingCompany.marry();
 }
}

动态代理

针对用户访问的数据接口

/**
 * 针对用户访问的数据接口
 */
public interface UserDao {
    
    /**
     * 添加功能
     */
    void add();

    /**
     * 修改功能
     */
    void update();

    /**
     * 查找功能
     */
    void select();

    /**
     * 删除功能
     */
    void delete();
}

针对用户数据访问接口的实现

public class UserDaoImpl implements  UserDao{

    public void add() {
        System.out.println("添加功能");
    }

    public void update() {
        System.out.println("修改功能");
    }

    public void select() {
        System.out.println("查询功能");
    }

    public void delete() {
        System.out.println("删除功能");
    }
}

基于代理的处理程序

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

/**
 * 基于代理的处理程序
 */

public class MyInvocation implements InvocationHandler{

      //针对谁产生代理 ud   UserDao ud = new UserDaoImpl();
    
    private  Object target;
    public MyInvocation(Object target){
        this.target=target;
 }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        
        System.out.println("权限校验");
       
        //调用接口中自己的方法,add(),update(),select(),delete();
        //当前实例---->真实角色
       
        Object obj = method.invoke(target, args);   //代理角色产生

        System.out.println("产生日志文件");
        return obj;
    }
}

测试代码

import java.lang.reflect.Proxy;


public class JdkProxyDemo {
    public static void main(String[] args) {
    
        UserDao ud = new UserDaoImpl(); //真实角色

        //前提是需要有一个接口
        //public static Obejct newProxyInstance(ClassLoader loader,Class<?>[]                             
         interfaces,InvocationHandler h)
        
        MyInvocation handler = new MyInvocation(ud);
        UserDao proxyInstance = (UserDao) Proxy.newProxyInstance(
                ud.getClass().getClassLoader(),
                ud.getClass().getInterfaces(),
                handler);
       
        proxyInstance.add();
        proxyInstance.update();
        proxyInstance.select();
        proxyInstance.delete();
    }
}

静态代理和动态代理主要有以下几点区别

  • 静态代理只能通过手动完成代理操作,如果被代理类增加了新的方法,则代理类需要同步增加,违背开闭原则
  • 动态代理采用在运行时动态生成代码的方式,取消了对被代理类的扩展限制,遵循开闭原则
  • 若动态代理要对目标类的增强逻辑进行扩展,结合策略模式,只需要新增策略类便可完成,无需修改代理类的代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值