设计模式---动态代理(基于JDK的动态代理)
2015-04-29 19:32
661 查看
1. 什么是动态代理?
代理是一种设计模式,它是为了提供额外的操作而插入的用来代替“实际”对象的对象。
2. 写一个我们自己的代理模式
2.1 项目结构
2.2 代码如下
接口层
package com.niepengfei.inface;
public interface PersonInface {
public void run();
}
实现层代码
package com.niepengfei.inface.impl;
import com.niepengfei.inface.PersonInface;
public class WomanImpl implements PersonInface {
@Override
public void run() {
System.out.println("我是实际对象,我跑。。。。。");
}
}
测试代码
package com.niepengfei.test;
import com.niepengfei.inface.PersonInface;
import com.niepengfei.inface.impl.SimplyProxy;
import com.niepengfei.inface.impl.WomanImpl;
public class ClientTest {
public static void main(String[] args) {
//被代理对象
PersonInface person = new WomanImpl();
//代理对象
PersonInface proxy = new SimplyProxy(person);
proxy.run();
}
}
3. 测试结果
4. 分析
5. 我们以JDK的代理为例,写一个简单的动态代理,看JDK的动态代理如何实现。
5.1 项目结构
5.2 代码
接口层
package com.niepengfei.inface;
public interface BoyInface {
public void speak();
}
package com.niepengfei.inface;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInvocationHandler implements InvocationHandler {
/**
* 被代理对象
*/
public Object proxied;
public MyInvocationHandler(Object proxied) {
super();
this.proxied = proxied;
}
/**
* 第一个参数proxy:代理对象,是由JVM动态生成
* 第二个参数method:是被代理对象的方法
* 第三个参数args:是被代理对象的方法的参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
System.out.println("我是代理对象,我是JVM动态生成的。。。。。。。。");
//调用处理器InvocationHandler将请求转发,调用被代理的对象的method方法
method.invoke(proxied, args);
System.out.println("我是代理对象,我结束调用。。。。。。。。");
return null;
}
}
实现层
package com.niepengfei.inface.impl;
import com.niepengfei.inface.BoyInface;
public class BoyImpl implements BoyInface {
@Override
public void speak() {
System.out.println("我是哑巴,我做手语。。");
}
}
测试代码
package com.niepengfei.test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import com.niepengfei.inface.BoyInface;
import com.niepengfei.inface.MyInvocationHandler;
import com.niepengfei.inface.impl.BoyImpl;
public class Test {
public static void main(String[] args) {
//被代理对象
BoyInface boy = new BoyImpl();
//调用处理器
InvocationHandler h = new MyInvocationHandler(boy);
//代理对象
BoyInface proxy = (BoyInface)Proxy.newProxyInstance(boy.getClass().getClassLoader(), boy.getClass().getInterfaces(), h);
proxy.speak();
}
}
5.3 测试结果
6. 分析
我们可以总结以下几点:
1. 为什么被代理对象的顶层必须是接口?
因为我们的动态代理类必须要继承JDK的Proxy类,还必须实现被代理对象所实现的所有接口。
2. 为什么可以直接转型BoyInface proxy = (BoyInface)Proxy.newProxyInstance(boy.getClass().getClassLoader(), boy.getClass().getInterfaces(), h);
因为我们的代理对象实现了所有被代理对象的接口。
代理是一种设计模式,它是为了提供额外的操作而插入的用来代替“实际”对象的对象。
2. 写一个我们自己的代理模式
2.1 项目结构
2.2 代码如下
接口层
package com.niepengfei.inface;
public interface PersonInface {
public void run();
}
实现层代码
package com.niepengfei.inface.impl;
import com.niepengfei.inface.PersonInface;
public class WomanImpl implements PersonInface {
@Override
public void run() {
System.out.println("我是实际对象,我跑。。。。。");
}
}
package com.niepengfei.inface.impl; import com.niepengfei.inface.PersonInface; public class SimplyProxy implements PersonInface { /** * 被代理对象 */ public PersonInface proxied; public SimplyProxy(PersonInface proxied) { super(); this.proxied = proxied; } @Override public void run() { System.out.println("我是代理对象,我跑。。。。"); proxied.run(); System.out.println("我是代理对象,我二次跑。。。。"); } }
测试代码
package com.niepengfei.test;
import com.niepengfei.inface.PersonInface;
import com.niepengfei.inface.impl.SimplyProxy;
import com.niepengfei.inface.impl.WomanImpl;
public class ClientTest {
public static void main(String[] args) {
//被代理对象
PersonInface person = new WomanImpl();
//代理对象
PersonInface proxy = new SimplyProxy(person);
proxy.run();
}
}
3. 测试结果
4. 分析
5. 我们以JDK的代理为例,写一个简单的动态代理,看JDK的动态代理如何实现。
5.1 项目结构
5.2 代码
接口层
package com.niepengfei.inface;
public interface BoyInface {
public void speak();
}
package com.niepengfei.inface;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInvocationHandler implements InvocationHandler {
/**
* 被代理对象
*/
public Object proxied;
public MyInvocationHandler(Object proxied) {
super();
this.proxied = proxied;
}
/**
* 第一个参数proxy:代理对象,是由JVM动态生成
* 第二个参数method:是被代理对象的方法
* 第三个参数args:是被代理对象的方法的参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
System.out.println("我是代理对象,我是JVM动态生成的。。。。。。。。");
//调用处理器InvocationHandler将请求转发,调用被代理的对象的method方法
method.invoke(proxied, args);
System.out.println("我是代理对象,我结束调用。。。。。。。。");
return null;
}
}
实现层
package com.niepengfei.inface.impl;
import com.niepengfei.inface.BoyInface;
public class BoyImpl implements BoyInface {
@Override
public void speak() {
System.out.println("我是哑巴,我做手语。。");
}
}
测试代码
package com.niepengfei.test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import com.niepengfei.inface.BoyInface;
import com.niepengfei.inface.MyInvocationHandler;
import com.niepengfei.inface.impl.BoyImpl;
public class Test {
public static void main(String[] args) {
//被代理对象
BoyInface boy = new BoyImpl();
//调用处理器
InvocationHandler h = new MyInvocationHandler(boy);
//代理对象
BoyInface proxy = (BoyInface)Proxy.newProxyInstance(boy.getClass().getClassLoader(), boy.getClass().getInterfaces(), h);
proxy.speak();
}
}
5.3 测试结果
6. 分析
我们可以总结以下几点:
1. 为什么被代理对象的顶层必须是接口?
因为我们的动态代理类必须要继承JDK的Proxy类,还必须实现被代理对象所实现的所有接口。
2. 为什么可以直接转型BoyInface proxy = (BoyInface)Proxy.newProxyInstance(boy.getClass().getClassLoader(), boy.getClass().getInterfaces(), h);
因为我们的代理对象实现了所有被代理对象的接口。
相关文章推荐
- JAVA设计模式之动态代理(JDK)
- Java设计模式--代理模式与JDK动态代理,cglib动态代理
- 设计模式之动态代理 jdk实现
- 设计模式之JDK动态代理和Cglib动态代理
- 设计模式--JDK动态代理的实现与原理解析(1)
- 设计模式之代理模式(静态代理、JDK动态代理和cglib动态代理)
- java与设计模式(五)-jdk动态代理模式
- 27 API-反射(类的加载器,反射的使用,动态代理)&设计模式(装饰设计模式,模版设计模式)&JDK新特性(JDK5,JDK6,JDK7,DK8)
- Java设计模式之代理模式2-动态代理(jdk实现)
- 设计模式——代理模式(静态代理和JDK、CGLib动态代理)
- 代理设计模式(普通静态代理、JDK动态代理、cglib动态代理)
- JDK设计模式之—动态代理
- Spring设计模式之JDK的动态代理!
- JAVA设计模式之【代理模式】二(jdk动态代理)
- 设计模式--JDK动态代理的实现与原理解析(2)
- 设计模式--动态代理(JDK)
- 基于jdk proxy的动态代理模式
- 设计模式之JDK动态代理
- 常用设计模式之动态代理1(JDK)
- 设计模式(2)--java动态代理及jdk和cglib的区别