
动态代理与静态代理最大的不同在于,动态代理中,代理类对象由JVM生成,不再需要我们自己编写代理类。
核心实现:
1. java.lang.reflect.Proxy类动态生成代理类和对象,它提供用于创建动态代理类和实例的静态方法,是由这些方法创建的所有动态代理类的超类。
2.java.lang.reflect.InvocationHandler处理器接口,可以通过invoke方法实现对真实角色的访问。(每次通过Proxy生成代理类对象时都要指定该处理器接口)
静态代理模式下,我们需要自定义代理类,其中UML类图如下:

动态代理模式下,代理类由Proxy类的静态方法newProxyInstance()创建,并关联处理器实例handler,而handler是继承自InvocationHandler接口的RoleHandler类的实例,handler包含了对真实角色RealRole的引用。UML类图如下:

我们先来看静态代理的实现(以婚礼为例说明):
UML类关系图:

详细代码:
package net.mosang.agent;
* A. 布置婚礼现场,不必情侣lovers亲自做,可由婚庆公司代理
* C. 招待宾客(接迎),不必情侣lovers亲自做,可由婚庆公司代理
public interface Wedding {
public void arrangement() ; //布置婚礼现场
public void weddingvows() ; //夫妻宣誓
public void entertainment(); //招待宾客
package net.mosang.agent;
/**
* 婚礼标准流程(接口):
* A. 布置婚礼现场,不必情侣lovers亲自做,可由婚庆公司代理
* B. 结婚宣誓,必须由情侣亲自做
* C. 招待宾客(接迎),不必情侣lovers亲自做,可由婚庆公司代理
* @author Heiry
*
*/
public interface Wedding {
public void arrangement() ; //布置婚礼现场
public void weddingvows() ; //夫妻宣誓
public void entertainment(); //招待宾客
}
package net.mosang.agent;
/**
* 婚礼标准流程(接口):
* A. 布置婚礼现场,不必情侣lovers亲自做,可由婚庆公司代理
* B. 结婚宣誓,必须由情侣亲自做
* C. 招待宾客(接迎),不必情侣lovers亲自做,可由婚庆公司代理
* @author Heiry
*
*/
public interface Wedding {
public void arrangement() ; //布置婚礼现场
public void weddingvows() ; //夫妻宣誓
public void entertainment(); //招待宾客
}
package net.mosang.agent;
* 婚礼主角:情侣Lovers,他们具备结婚标准流程要求的技能,但不一定需要用上
public class Lovers implements Wedding{
private String bridegroom; //新郎姓名
private String bride; //新娘姓名
public void arrangement() {
System.out.println("新郎:"+this.bridegroom +"与新娘:"+ this.bride + "布置了婚礼现场");//情侣亲自布置
public void weddingvows() {
System.out.println("新郎-->"+this.bridegroom +"与新娘-->"+ this.bride + "宣誓结婚"); // 情侣结婚宣誓词
public void entertainment() {
System.out.println("新郎:"+this.bridegroom +"与新娘:"+ this.bride + "招待宾客");//情侣亲自接待宾客
public Lovers(String bridegroom, String bride) {
this.bridegroom = bridegroom;
package net.mosang.agent;
/**
* 婚礼主角:情侣Lovers,他们具备结婚标准流程要求的技能,但不一定需要用上
*
* @author Heiry
*
*/
public class Lovers implements Wedding{
private String bridegroom; //新郎姓名
private String bride; //新娘姓名
@Override
public void arrangement() {
System.out.println("新郎:"+this.bridegroom +"与新娘:"+ this.bride + "布置了婚礼现场");//情侣亲自布置
}
@Override
public void weddingvows() {
System.out.println("新郎-->"+this.bridegroom +"与新娘-->"+ this.bride + "宣誓结婚"); // 情侣结婚宣誓词
}
@Override
public void entertainment() {
System.out.println("新郎:"+this.bridegroom +"与新娘:"+ this.bride + "招待宾客");//情侣亲自接待宾客
}
public Lovers(String bridegroom, String bride) {
super();
this.bridegroom = bridegroom;
this.bride = bride;
}
}
package net.mosang.agent;
/**
* 婚礼主角:情侣Lovers,他们具备结婚标准流程要求的技能,但不一定需要用上
*
* @author Heiry
*
*/
public class Lovers implements Wedding{
private String bridegroom; //新郎姓名
private String bride; //新娘姓名
@Override
public void arrangement() {
System.out.println("新郎:"+this.bridegroom +"与新娘:"+ this.bride + "布置了婚礼现场");//情侣亲自布置
}
@Override
public void weddingvows() {
System.out.println("新郎-->"+this.bridegroom +"与新娘-->"+ this.bride + "宣誓结婚"); // 情侣结婚宣誓词
}
@Override
public void entertainment() {
System.out.println("新郎:"+this.bridegroom +"与新娘:"+ this.bride + "招待宾客");//情侣亲自接待宾客
}
public Lovers(String bridegroom, String bride) {
super();
this.bridegroom = bridegroom;
this.bride = bride;
}
}
package net.mosang.agent;
* 婚庆代理公司: 帮助情侣打理除了宣誓之外的所有事务
public class WeddingAgent implements Wedding {
public void arrangement() {
System.out.println("婚庆公司布置婚礼现场");//婚庆公司布置婚礼现场
public void weddingvows() {
Lovers.weddingvows(); //由情侣亲自做
public void entertainment() {
System.out.println("婚庆公司招待宾客");//婚庆公司招待宾客
public WeddingAgent(Lovers lovers) {
package net.mosang.agent;
/**
* 婚庆代理公司: 帮助情侣打理除了宣誓之外的所有事务
* @author Heiry
*
*/
public class WeddingAgent implements Wedding {
private Lovers Lovers;
@Override
public void arrangement() {
System.out.println("婚庆公司布置婚礼现场");//婚庆公司布置婚礼现场
}
@Override
public void weddingvows() {
Lovers.weddingvows(); //由情侣亲自做
}
@Override
public void entertainment() {
System.out.println("婚庆公司招待宾客");//婚庆公司招待宾客
}
public WeddingAgent(Lovers lovers) {
super();
this.Lovers = lovers;
}
}
package net.mosang.agent;
/**
* 婚庆代理公司: 帮助情侣打理除了宣誓之外的所有事务
* @author Heiry
*
*/
public class WeddingAgent implements Wedding {
private Lovers Lovers;
@Override
public void arrangement() {
System.out.println("婚庆公司布置婚礼现场");//婚庆公司布置婚礼现场
}
@Override
public void weddingvows() {
Lovers.weddingvows(); //由情侣亲自做
}
@Override
public void entertainment() {
System.out.println("婚庆公司招待宾客");//婚庆公司招待宾客
}
public WeddingAgent(Lovers lovers) {
super();
this.Lovers = lovers;
}
}
package net.mosang.agent;
public static void main(String[] args) {
Lovers lovers = new Lovers("牛郎", "织女"); //创建牛郎织女新人实例
WeddingAgent weddingAgent = new WeddingAgent(lovers); //创建婚庆公司实例
* 整个婚礼完全由婚庆代理主导,外界无需知道婚礼主角在其中具体的操作
weddingAgent.arrangement();
weddingAgent.weddingvows();
weddingAgent.entertainment();
package net.mosang.agent;
/**
* 客户端测试
* @author Heiry
*
*/
public class Client {
public static void main(String[] args) {
Lovers lovers = new Lovers("牛郎", "织女"); //创建牛郎织女新人实例
WeddingAgent weddingAgent = new WeddingAgent(lovers); //创建婚庆公司实例
/**
* 整个婚礼完全由婚庆代理主导,外界无需知道婚礼主角在其中具体的操作
*/
weddingAgent.arrangement();
weddingAgent.weddingvows();
weddingAgent.entertainment();
}
}
package net.mosang.agent;
/**
* 客户端测试
* @author Heiry
*
*/
public class Client {
public static void main(String[] args) {
Lovers lovers = new Lovers("牛郎", "织女"); //创建牛郎织女新人实例
WeddingAgent weddingAgent = new WeddingAgent(lovers); //创建婚庆公司实例
/**
* 整个婚礼完全由婚庆代理主导,外界无需知道婚礼主角在其中具体的操作
*/
weddingAgent.arrangement();
weddingAgent.weddingvows();
weddingAgent.entertainment();
}
}
输出结果
婚庆公司布置婚礼现场
新郎-->牛郎与新娘-->织女宣誓结婚
婚庆公司招待宾客
婚庆公司布置婚礼现场
新郎-->牛郎与新娘-->织女宣誓结婚
婚庆公司招待宾客
下面用动态代理来实现:
package net.mosang.agent;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class WeddingHandler implements InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("婚庆公司布置现场");
if(method.getName().equals("weddingvows")) {
method.invoke(lovers, args);
System.out.println("婚庆公司接送宾客");
public WeddingHandler(Lovers lovers) {
package net.mosang.agent;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class WeddingHandler implements InvocationHandler {
private Lovers lovers;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("婚庆公司布置现场");
if(method.getName().equals("weddingvows")) {
method.invoke(lovers, args);
}
System.out.println("婚庆公司接送宾客");
return null;
}
public WeddingHandler(Lovers lovers) {
super();
this.lovers = lovers;
}
}
package net.mosang.agent;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class WeddingHandler implements InvocationHandler {
private Lovers lovers;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("婚庆公司布置现场");
if(method.getName().equals("weddingvows")) {
method.invoke(lovers, args);
}
System.out.println("婚庆公司接送宾客");
return null;
}
public WeddingHandler(Lovers lovers) {
super();
this.lovers = lovers;
}
}
package net.mosang.agent;
import java.lang.reflect.Proxy;
public class ClientDynamic {
public static void main(String[] args) {
Lovers lovers = new Lovers("牛郎", "织女");
WeddingHandler weddingHandler = new WeddingHandler(lovers);
Wedding proxy =(Wedding) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[] {Wedding.class}, weddingHandler);
package net.mosang.agent;
import java.lang.reflect.Proxy;
public class ClientDynamic {
public static void main(String[] args) {
Lovers lovers = new Lovers("牛郎", "织女");
WeddingHandler weddingHandler = new WeddingHandler(lovers);
Wedding proxy =(Wedding) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[] {Wedding.class}, weddingHandler);
proxy.weddingvows();
}
}
package net.mosang.agent;
import java.lang.reflect.Proxy;
public class ClientDynamic {
public static void main(String[] args) {
Lovers lovers = new Lovers("牛郎", "织女");
WeddingHandler weddingHandler = new WeddingHandler(lovers);
Wedding proxy =(Wedding) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[] {Wedding.class}, weddingHandler);
proxy.weddingvows();
}
}
输出结果:
婚庆公司布置现场
新郎-->牛郎与新娘-->织女宣誓结婚
婚庆公司接送宾客
婚庆公司布置现场
新郎-->牛郎与新娘-->织女宣誓结婚
婚庆公司接送宾客
动态代理的实质探究
通过以上代码,初学者对动态代理实现机制可能还是云里雾里,知其然不知其所以然,所以在这里还是有必要梳理清楚。
现在我们有一个接口Dream(代码如下),我们知道要使用一个接口,就要编写其实现类并实例化:
package net.mosang.agent;
public void doSomething();
package net.mosang.agent;
/**
* 代理模式深入探究
* @author Heiry
*
*/
public interface Dream {
public void doSomething();
}
package net.mosang.agent;
/**
* 代理模式深入探究
* @author Heiry
*
*/
public interface Dream {
public void doSomething();
}
package net.mosang.agent;
public class MyDream implements Dream {
public void doSomething() {
System.out.println("I wanna be a great program engineer,just like Dennis MacAlistair Ritchie!");
package net.mosang.agent;
/**
* Dream接口的实现类MyDream
* @author Heiry
*
*/
public class MyDream implements Dream {
@Override
public void doSomething() {
System.out.println("I wanna be a great program engineer,just like Dennis MacAlistair Ritchie!");
}
}
package net.mosang.agent;
/**
* Dream接口的实现类MyDream
* @author Heiry
*
*/
public class MyDream implements Dream {
@Override
public void doSomething() {
System.out.println("I wanna be a great program engineer,just like Dennis MacAlistair Ritchie!");
}
}
package net.mosang.agent;
public class DreamComeTrue {
public static void main(String[] args) {
Dream myDream = new MyDream(); //多态方式创建实例
myDream.doSomething(); //输出“I wanna be a great program engineer,just like Dennis MacAlistair Ritchie!”
package net.mosang.agent;
/**
* 测试类
* @author Heiry
*
*/
public class DreamComeTrue {
public static void main(String[] args) {
Dream myDream = new MyDream(); //多态方式创建实例
myDream.doSomething(); //输出“I wanna be a great program engineer,just like Dennis MacAlistair Ritchie!”
}
}
package net.mosang.agent;
/**
* 测试类
* @author Heiry
*
*/
public class DreamComeTrue {
public static void main(String[] args) {
Dream myDream = new MyDream(); //多态方式创建实例
myDream.doSomething(); //输出“I wanna be a great program engineer,just like Dennis MacAlistair Ritchie!”
}
}
如果我们不编写实现类,有没有办法运行期直接创建Dream的实现类?这似乎与接口的使用规则背道而驰,因为接口是不能实例化的,然而java提供的动态代理机制允许在运行期动态创建接口的实例。
这种没有实现类但在运行期动态创建了一个接口对象的方式,我们称为动态代码。
package net.mosang.agent;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DreamComeTrue {
public static void main(String[] args) {
// Dream myDream = new MyDream(); //多态方式创建实例
// myDream.doSomething();
InvocationHandler handler = new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method);
System.out.println("Your dream is wonderful!");
Dream yourDream = (Dream) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[] {Dream.class}, handler);
package net.mosang.agent;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 测试类
* @author Heiry
*
*/
public class DreamComeTrue {
public static void main(String[] args) {
// Dream myDream = new MyDream(); //多态方式创建实例
// myDream.doSomething();
InvocationHandler handler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method);
System.out.println("Your dream is wonderful!");
return null;
}
};
Dream yourDream = (Dream) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[] {Dream.class}, handler);
yourDream.doSomething();
}
}
package net.mosang.agent;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 测试类
* @author Heiry
*
*/
public class DreamComeTrue {
public static void main(String[] args) {
// Dream myDream = new MyDream(); //多态方式创建实例
// myDream.doSomething();
InvocationHandler handler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method);
System.out.println("Your dream is wonderful!");
return null;
}
};
Dream yourDream = (Dream) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[] {Dream.class}, handler);
yourDream.doSomething();
}
}
public abstract void net.mosang.agent.Dream.doSomething()
public abstract void net.mosang.agent.Dream.doSomething()
Your dream is wonderful!
public abstract void net.mosang.agent.Dream.doSomething()
Your dream is wonderful!
通过动态代码,我们可以动态实现一个接口的实例对象,实际上就是静态代理中的代理对象,只不过这个代理对象不是事先编写好的,而是运行期动态创建的。