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的静态代理和动态代理都能实现对目标对象的代理,但静态代理需要手动创建代理类,适用于目标类数量固定且已知的情况;而动态代理则在运行时生成代理类,更加灵活,尤其适合处理数量不确定或动态变化的...
代理设计模式分为静态代理和动态代理两种类型。 ### 静态代理 静态代理是在编译时就已经确定了代理关系,代理类和真实类的关系是硬编码在代理类中的。下面我们将详细介绍静态代理的实现方式: 1. **定义接口**:...
Java提供了两种实现代理的主要方式:静态代理和动态代理。 **静态代理** 静态代理是最基础的形式,它需要程序员手动创建一个代理类,该类实现了与目标类相同的接口。代理类持有目标类的引用,并在调用目标类方法...
代理模式通常分为静态代理和动态代理两种类型,这两种代理方式各有特点,适用于不同的场景。 **静态代理** 静态代理是通过程序员手动创建一个代理类来实现的。代理类和真实目标类需要实现相同的接口,以便代理类...
java提高-动态代理与静态代理.docx
Java静态代理模式是一种设计模式,它允许我们为一个对象提供一个代理,以便增强或扩展其功能,同时不改变原有对象的代码。在Java中,静态代理是通过在代理类中显式实现目标接口来实现的。下面将详细介绍静态代理模式...
Java 动态代理详解(代理模式+静态代理+JDK动态代理+CGLIB动态代理) Java 动态代理是 Java 编程语言中的一种强大工具,广泛应用于 Spring AOP、Hibernate 数据查询、测试框架的后端 mock、RPC 远程调用、Java 注解...
在Java中,代理主要分为静态代理和动态代理。 1. 静态代理: 静态代理是在编译时就已经明确代理类与被代理类关系的一种方式。为了实现静态代理,我们需要手动创建一个代理类,这个代理类通常会实现与被代理类相同的...
根据实现方式的不同,代理模式可以分为静态代理和动态代理两种。 ### 静态代理 静态代理是在编译时就已经确定了代理关系。我们需要创建一个代理类,该类实现与目标对象相同的接口,并在代理类的方法中调用目标对象...
Java提供了两种主要的代理实现方式:静态代理和动态代理。 ### 静态代理 静态代理是在编译时就已经确定了代理关系。首先,我们需要定义一个接口,比如`Car`,这个接口描述了汽车的行为: ```java public ...
代理模式可以进一步细分为静态代理和动态代理。 - **静态代理**:在程序编译时就已经确定代理类的具体实现方式。这意味着每次需要代理不同的操作时,都需要修改代理类的代码,这违反了软件工程中的开闭原则。 - **...
静态代理和动态代理是两种常见的代理模式,它们在Java中有着广泛的应用,特别是在SpringBoot等框架中。本资源提供了一个简单的Java实现,适用于JDK1.8版本,并经过了验证,对初学者理解设计模式具有指导意义。 静态...
在这个“包含静态代理和动态代理demo代码”的压缩包中,我们可能会看到两种常见的Java代理实现方式的示例:静态代理和动态代理。 首先,我们来详细讲解静态代理。在静态代理中,代理类和真实类(目标类)都是在编译...