`

java代理之静态和动态

    博客分类:
  • java
阅读更多

1.    静态代理(可以面向接口,也可以面向类):

执行入口是代理类,目标类在代理中注册执行

静态代理实例

public interface HKworkday {         //接口
    public void HKeat(); 
    public void HKdo(String work); 

public class HKworkdayImpl implements HKworkday {  //实现类
    @Override 
    public void HKeat() { 
    System.out.println("HKworkdayImpl.HKeat()"); 
    } 
    @Override 
    public void HKdo(String work) { 
    System.out.println("HKworkdayImpl.HKdo(" + work + ")"); 
    } 
}
public class HKweekday {   //父类
    public void HKplay() { 
    System.out.println("HKweekday.HKplay()"); 
    }
}
public class StaticProxy extends HKweekday implements HKworkday {  //继承HKweekday,实现HKworkday
    private HKworkday workday;
    private HKweekday weekday;
    public StaticProxy(HKworkday workday, HKweekday weekday) {
        this.workday = workday;
    this.weekday = weekday;
    } 
    @Override 
    public void HKeat() {  //重写方法
        System.out.println(" before HKworkdayImpl.HKeat()"); 
        workday.HKeat(); 
        System.out.println(" after HKworkdayImpl.HKeat()"); 
    } 
    @Override 
    public void HKdo(String work) {  //重写方法
        System.out.println("before HKworkdayImpl.HKdo(" + work + ")"); 
        workday.HKdo(work); 
        System.out.println("after HKworkdayImpl.HKdo(" + work + ")"); 
    }
    @Override
    public void HKplay() {  //重写方法
        System.out.println("before HKweekdayImpl.HKplay()"); 
        weekday.HKplay(); 
        System.out.println("after HKweekdayImpl.HKplay()"); 
    } 

public class StaticProxyMain { 
    public static void main(String[] args) { 
    HKworkday workday = new HKworkdayImpl();
    HKweekday weekday = new HKweekday();
    workday.HKeat(); 
    workday.HKdo("software"); 
    weekday.HKplay();
    StaticProxy proxy = new StaticProxy(workday, weekday); 
    proxy.HKeat(); 
    proxy.HKdo("software");
        proxy.HKplay();
    } 

其实,静态代理的关键是将目标对象,作为代理类的属性,在代理类中注册,在代理类的方法中调用目标对象方法,并在目标对象方法前后织入代码,但是需要使用代理类功能的目标类方法,都要在代理类中实现,如此一来,原来的直接体现业务逻辑流程的代码,要用代理改写,而改写后,通过阅读代码很难理解业务逻辑流程;至于代理类是否extends目标对象的类,或者implements目标对象的类,会影响代理类中的代码编写方法;因此java静态代理的实现,跟类或者接口是无关的,都能实现

 

2.    动态代理(面向接口)

执行入口是目标类,代理类通过java反射和代理机制在目标中注册执行,由JDK创建

动态代理实例

import java.lang.reflect.InvocationHandler; 
import java.lang.reflect.Method;
public interface HKworkday {  //接口
    public void HKeat(); 
    public void HKdo(String work); 

public interface HKweekday {  //接口
    public void HKplay();
}
public class HKlife implements HKworkday, HKweekday {   //实现类
    @Override 
    public void HKeat() { 
        System.out.println("HKlife.HKeat()"); 
    } 
    @Override 
    public void HKdo(String work) { 
        System.out.println("HKlife.HKdo(" + work + ")"); 
    } 
    @Override 
    public void HKplay() { 
        System.out.println("HKlife.HKplay()"); 
    }
}
public class DynamicProxy implements InvocationHandler { //代理
    private Object proxied; 
    public DynamicProxy(Object proxied) { 
        this.proxied = proxied; 
    }
    @Override 
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 
        System.out.println("----START----");  
        Object obj = method.invoke(proxied, args);    // java的反射
        System.out.println("----END----"); 
        return obj; 
    } 
}  
public class DynamicProxyMain {   
    public static void main(String[] args) { 
        Object obj = Proxy.newProxyInstance(HKworkday.class.getClassLoader(), new Class<?>[] { HKworkday.class, HKweekday.class }, new DynamicProxy(new HKlife())); 
        HKworkday workday = (HKworkday) obj; 
        workday.HKeat(); 
        workday.HKdo("software"); 
        HKweekday weekday = (HKweekday) obj; 
        weekday.HKplay();
    } 

相较于静态代理而言,JDK动态代理是通过java的反射和代理机制,将代理类的功能反向注入到目标类中,因此,原来体现业务逻辑流程的代码在不需要过多的人工改变情况下,就可以完成目标类的功能和代理类的功能组合。通过阅读源代码,还是很容易理解业务逻辑流程,只是在执行时会在逻辑流程的前后,被自动织入代理类功能。

 

3.    代理的使用

       A.  静态代理的实现需要花时间写大量代码,并且干扰原有的业务逻辑代码,因此大部分的开发中都不使用静态代理,静态代理的性能无问题;

       B.  动态代理使用java的代理机制(JDK动态代理),只能面向接口(由Proxy.newProxyInstance()第二个参数能说明这一点),对接口中的所有方法自动加入代理功能,并且不会干扰原有的业务逻辑代码,因此比较常用;

       C.  由于java的动态代理只能面向接口,某些时候项目的业务类不需要接口,而静态代理的诸多不便,怎么办呢?

            使用cglib第三方jar包,cglib采用底层的字节码技术,为代理对象创建一个子类,在子类中采用方法拦截技术,拦截父类方法的调用,并织入通用业务功能(面向类的动态代理),但是加载导入的cglib包耗时间,cglib在创建动态代理对象时所花费的时间比 jdk要多(8倍),但是,cglib所创建的动态代理对象的性能比jdk所创建的动态代理对象的性能高很多(10倍左右),对于单例模式对象的代理或者具有实例池(类似于数据库连接池、线程池)的代理,因为不需要频繁创建代理对象,所以适用cglib动态代理;频繁创建代理对象的情况适合用jdk动态代理。

分享到:
评论

相关推荐

    JAVA静态代理和动态代理

    Java提供了两种主要的代理实现方式:静态代理和动态代理。 **静态代理** 静态代理是程序员手动创建代理类并实现与目标对象相同的接口。代理类和目标类都必须实现相同的接口,这样代理类就可以在调用目标对象方法的...

    Java静态代理和动态代理

    Java的代理模式通过代理类提供了对委托类的扩展和控制,静态代理适合对已有代码不做修改的情况,而动态代理则提供了更高的灵活性和扩展性。在实际应用中,应根据项目需求和性能考虑选择静态代理或动态代理。对于需要...

    Java静态代理与动态代理demo

    总结来说,Java的静态代理和动态代理都能实现对目标对象的代理,但静态代理需要手动创建代理类,适用于目标类数量固定且已知的情况;而动态代理则在运行时生成代理类,更加灵活,尤其适合处理数量不确定或动态变化的...

    Java设计模式——代理设计模式(静态代理和动态代理)

    代理设计模式分为静态代理和动态代理两种类型。 ### 静态代理 静态代理是在编译时就已经确定了代理关系,代理类和真实类的关系是硬编码在代理类中的。下面我们将详细介绍静态代理的实现方式: 1. **定义接口**:...

    java静态代理、动态代理、装饰设计模式

    Java提供了两种实现代理的主要方式:静态代理和动态代理。 **静态代理** 静态代理是最基础的形式,它需要程序员手动创建一个代理类,该类实现了与目标类相同的接口。代理类持有目标类的引用,并在调用目标类方法...

    java 静态代理和动态代理学习实例源码

    代理模式通常分为静态代理和动态代理两种类型,这两种代理方式各有特点,适用于不同的场景。 **静态代理** 静态代理是通过程序员手动创建一个代理类来实现的。代理类和真实目标类需要实现相同的接口,以便代理类...

    java提高-动态代理与静态代理.docx

    java提高-动态代理与静态代理.docx

    Java 静态代理模式

    Java静态代理模式是一种设计模式,它允许我们为一个对象提供一个代理,以便增强或扩展其功能,同时不改变原有对象的代码。在Java中,静态代理是通过在代理类中显式实现目标接口来实现的。下面将详细介绍静态代理模式...

    Java 动态代理详解(代理模式+静态代理+JDK动态代理+CGLIB动态代理)

    Java 动态代理详解(代理模式+静态代理+JDK动态代理+CGLIB动态代理) Java 动态代理是 Java 编程语言中的一种强大工具,广泛应用于 Spring AOP、Hibernate 数据查询、测试框架的后端 mock、RPC 远程调用、Java 注解...

    java静态代理和动态代理详解

    在Java中,代理主要分为静态代理和动态代理。 1. 静态代理: 静态代理是在编译时就已经明确代理类与被代理类关系的一种方式。为了实现静态代理,我们需要手动创建一个代理类,这个代理类通常会实现与被代理类相同的...

    静态代理和动态代理

    根据实现方式的不同,代理模式可以分为静态代理和动态代理两种。 ### 静态代理 静态代理是在编译时就已经确定了代理关系。我们需要创建一个代理类,该类实现与目标对象相同的接口,并在代理类的方法中调用目标对象...

    java静态代理和动态代理

    Java提供了两种主要的代理实现方式:静态代理和动态代理。 ### 静态代理 静态代理是在编译时就已经确定了代理关系。首先,我们需要定义一个接口,比如`Car`,这个接口描述了汽车的行为: ```java public ...

    Java 代理 代理模式 静态代理与动态代理 常见的动态代理实现 .md

    代理模式可以进一步细分为静态代理和动态代理。 - **静态代理**:在程序编译时就已经确定代理类的具体实现方式。这意味着每次需要代理不同的操作时,都需要修改代理类的代码,这违反了软件工程中的开闭原则。 - **...

    静态代理和动态代理Demo

    静态代理和动态代理是两种常见的代理模式,它们在Java中有着广泛的应用,特别是在SpringBoot等框架中。本资源提供了一个简单的Java实现,适用于JDK1.8版本,并经过了验证,对初学者理解设计模式具有指导意义。 静态...

    包含静态代理和动态代理demo代码

    在这个“包含静态代理和动态代理demo代码”的压缩包中,我们可能会看到两种常见的Java代理实现方式的示例:静态代理和动态代理。 首先,我们来详细讲解静态代理。在静态代理中,代理类和真实类(目标类)都是在编译...

Global site tag (gtag.js) - Google Analytics