黑马程序员:Java基础总结----静态代理模式&动态代理
2013-07-14 16:10
741 查看
黑马程序员:Java基础总结
静态代理模式&动态代理
ASP.Net+Android+IO开发、.Net培训、期待与您交流!
静态代理模式
public class Ts
{
public static void main(String[]
args) throws Exception {
[align=left] // 通过中介公司生产一批衣服[/align]
[align=left] ClothingProduct cp = new ProxCompany(new LiNingCompany());[/align]
[align=left] cp.productClothing();[/align]
[align=left] }[/align]
[align=left]}[/align]
[align=left]/**[/align]
[align=left] * 定义生产一批衣服功能的接口[/align]
[align=left] *[/align]
[align=left] */[/align]
[align=left]interface ClothingProduct {[/align]
void productClothing(); //
有生产一批衣服的功能
[align=left]}[/align]
[align=left]/**[/align]
[align=left] *[/align]
[align=left] * 代理类:中介公司[/align]
[align=left] *[/align]
[align=left] */[/align]
class ProxCompany implements ClothingProduct
{
private ClothingProduct cp ; //
中介公司不会生产衣服,需要找一家真正能生产衣服的公司
[align=left] ProxCompany(ClothingProduct cp) {[/align]
[align=left] super();[/align]
this.cp =
cp;
[align=left] }[/align]
[align=left] @Override[/align]
public void productClothing()
{
[align=left] System. out.println("收取1000块钱的中介费" );[/align]
[align=left] cp.productClothing();[/align]
[align=left] }[/align]
[align=left]}[/align]
[align=left]/**[/align]
[align=left] *[/align]
[align=left] * 李宁公司是生产服装的目标类[/align]
[align=left] *[/align]
[align=left] */[/align]
class LiNingCompany implements ClothingProduct
{
[align=left] @Override[/align]
public void productClothing()
{
[align=left] System. out.println("生产一批衣服。。。。" );[/align]
[align=left] }[/align]
[align=left]}[/align]
上面程序的做法,使用的模式是静态代理模式
静态代理模式在现实编程中的弊端:
它的特征是代理类和目标对象的类都是在编译期间确定下来的,不利于程序上的扩展,上面示例中,如果客户还想找一个“生产一批鞋子”的工厂,那么还需要新增加一个代理类和一个目标类。如果客户还需要很多其他的服务,就必须一一的添加代理类和目标类。那就需要写很多的代理类和目标类
动态代理技术
java.lang.reflect
类 Proxy
每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的
[align=left]import java.lang.reflect.InvocationHandler;[/align]
[align=left]import java.lang.reflect.Method;[/align]
[align=left]import java.lang.reflect.Proxy;[/align]
[align=left]import java.util.ArrayList;[/align]
[align=left]import java.util.Collection;[/align]
public class Ts
{
public static void main(String[]
args) throws Exception {
[align=left] ArrayList test = new ArrayList();[/align]
//
代理只可以强转换成接口
[align=left] Collection list = (Collection ) getProxy(test, new MyAdvice());[/align]
[align=left] list.add(123);[/align]
[align=left] list.add(123);[/align]
[align=left] System. out.println(list);[/align]
[align=left] }[/align]
public staticObject
getProxy(finalObject target, final Advice
adv)/* 终态是因为内部类调用 */ {
//
返回一个指定接口的代理类实例 obj
[align=left] Object obj = Proxy. newProxyInstance([/align]
//
定义代理类的类加载器
[align=left] target.getClass().getClassLoader(),[/align]
//
代理类要实现的接口列表
[align=left] target.getClass().getInterfaces(),[/align]
//
指派方法调用的调用处理程序 InvocationHandler
new InvocationHandler()
{
[align=left] @Override[/align]
publicObject
invoke(Object proxy, Method method,
Object[] args) throws Throwable
{
[align=left] adv.begintime(method);[/align]
//target目标
,args方法参数,调用原来的方法
[align=left] Object retVal = method.invoke(target, args);[/align]
[align=left] adv.endtime(method);[/align]
[align=left] return retVal;[/align]
[align=left] }[/align]
[align=left] });[/align]
[align=left] return obj;[/align]
[align=left] }[/align]
[align=left]}[/align]
[align=left]//插入的建议接口[/align]
interface Advice
{
void begintime(Method
method);
void endtime(Method
method);
[align=left]}[/align]
[align=left]//我的建议[/align]
class MyAdvice implements Advice
{
[align=left] @Override[/align]
public void begintime(Method
method) {
[align=left] Long time = System. currentTimeMillis();[/align]
System. out.println(method.getName()
+ time);
[align=left] }[/align]
[align=left] @Override[/align]
public void endtime(Method
method) {
[align=left] Long time = System. currentTimeMillis();[/align]
System. out.println(method.getName()
+ time);
[align=left] }[/align]
[align=left]}[/align]
一个更巧妙的方法:自定义一个处理程序
public class Ts
{
public static void main(String[]
args) throws Exception {
[align=left] ProxyHandler handler= new ProxyHandler();[/align]
[align=left] ClothingProduct cp2=(ClothingProduct)handler.newProxyInstance( new LiNingCompany());[/align]
[align=left] cp2.productClothing();[/align]
[align=left] }[/align]
[align=left]}[/align]
class ProxyHandler implements InvocationHandler
{
/*
目标对象 */
[align=left] privateObject target ;[/align]
/*
创建目标对象的代理对象 */
publicObject
newProxyInstance(Object target) {
this.target =
target;
[align=left] /*[/align]
[align=left] * 第一个参数:定义代理类的类加载器[/align]
[align=left] * 第二个参数:代理类要实现的接口 列表[/align]
[align=left] * 第三个参数:指派方法调用的调用处理程序[/align]
[align=left] */[/align]
[align=left] return Proxy.newProxyInstance(this. target.getClass().getClassLoader(),[/align]
[align=left] this.target .getClass().getClasses(), this);[/align]
[align=left] }[/align]
[align=left] @Override[/align]
publicObject
invoke(Object proxy, Method method,Object[] args)
throws Throwable
{
[align=left] Object result = null;[/align]
[align=left] System. out.println("目标对象上的方法调用之前可以添加其他代码。。。" );[/align]
result = method.invoke( this.target ,
args); // 通过反射调用目标对象上的方法
[align=left] System. out.println("目标对象上的方法调用之后可以添加其他代码。。。" );[/align]
[align=left] return result;[/align]
[align=left] }[/align]
[align=left]}[/align]
ASP.Net+Android+IO开发、.Net培训、期待与您交流!
静态代理模式&动态代理
ASP.Net+Android+IO开发、.Net培训、期待与您交流!
静态代理模式
public class Ts
{
public static void main(String[]
args) throws Exception {
[align=left] // 通过中介公司生产一批衣服[/align]
[align=left] ClothingProduct cp = new ProxCompany(new LiNingCompany());[/align]
[align=left] cp.productClothing();[/align]
[align=left] }[/align]
[align=left]}[/align]
[align=left]/**[/align]
[align=left] * 定义生产一批衣服功能的接口[/align]
[align=left] *[/align]
[align=left] */[/align]
[align=left]interface ClothingProduct {[/align]
void productClothing(); //
有生产一批衣服的功能
[align=left]}[/align]
[align=left]/**[/align]
[align=left] *[/align]
[align=left] * 代理类:中介公司[/align]
[align=left] *[/align]
[align=left] */[/align]
class ProxCompany implements ClothingProduct
{
private ClothingProduct cp ; //
中介公司不会生产衣服,需要找一家真正能生产衣服的公司
[align=left] ProxCompany(ClothingProduct cp) {[/align]
[align=left] super();[/align]
this.cp =
cp;
[align=left] }[/align]
[align=left] @Override[/align]
public void productClothing()
{
[align=left] System. out.println("收取1000块钱的中介费" );[/align]
[align=left] cp.productClothing();[/align]
[align=left] }[/align]
[align=left]}[/align]
[align=left]/**[/align]
[align=left] *[/align]
[align=left] * 李宁公司是生产服装的目标类[/align]
[align=left] *[/align]
[align=left] */[/align]
class LiNingCompany implements ClothingProduct
{
[align=left] @Override[/align]
public void productClothing()
{
[align=left] System. out.println("生产一批衣服。。。。" );[/align]
[align=left] }[/align]
[align=left]}[/align]
上面程序的做法,使用的模式是静态代理模式
静态代理模式在现实编程中的弊端:
它的特征是代理类和目标对象的类都是在编译期间确定下来的,不利于程序上的扩展,上面示例中,如果客户还想找一个“生产一批鞋子”的工厂,那么还需要新增加一个代理类和一个目标类。如果客户还需要很多其他的服务,就必须一一的添加代理类和目标类。那就需要写很多的代理类和目标类
动态代理技术
java.lang.reflect
类 Proxy
Proxy提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。
构造方法摘要 | |
---|---|
protected | Proxy(InvocationHandler h) 使用其调用处理程序的指定值从子类(通常为动态代理类)构建新的 Proxy实例。 |
字段摘要 | |
---|---|
protected InvocationHandler | h 此代理实例的调用处理程序。 |
方法摘要 | |
---|---|
static InvocationHandler | getInvocationHandler(Object proxy) 返回指定代理实例的调用处理程序。 |
static Class<?> | getProxyClass(ClassLoader loader, Class<?>... interfaces) 返回代理类的 java.lang.Class对象,并向其提供类加载器和接口数组。 |
static boolean | isProxyClass(Class<?> cl) 当且仅当指定的类通过 getProxyClass方法或 newProxyInstance方法动态生成为代理类时,返回 true。 |
staticObject | newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。 |
invoke方法。
public interface InvocationHandler 方法摘要 | |
---|---|
Object | invoke(Object proxy, Method method,Object[] args) 在代理实例上处理方法调用并返回结果。 参数: proxy- 在其上调用方法的代理实例 method- 对应于在代理实例上调用的接口方法的 Method实例。 Method对象的声明类将是在其中声明方法的接口,该接口可以是代理类赖以继承方法的代理接口的超接口。 args- 包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为 null。基本类型的参数被包装在适当基本包装器类(如 java.lang.Integer或 java.lang.Boolean)的实例中。返回:从代理实例的方法调用返回的值。如果接口方法的声明返回类型是基本类型,则此方法返回的值一定是相应基本包装对象类的实例;否则,它一定是可分配到声明返回类型的类型。如果此方法返回的值为 null并且接口方法的返回类型是基本类型,则代理实例上的方法调用将抛出 NullPointerException。否则,如果此方法返回的值与上述接口方法的声明返回类型不兼容,则代理实例上的方法调用将抛出 ClassCastException。 |
[align=left]import java.lang.reflect.Method;[/align]
[align=left]import java.lang.reflect.Proxy;[/align]
[align=left]import java.util.ArrayList;[/align]
[align=left]import java.util.Collection;[/align]
public class Ts
{
public static void main(String[]
args) throws Exception {
[align=left] ArrayList test = new ArrayList();[/align]
//
代理只可以强转换成接口
[align=left] Collection list = (Collection ) getProxy(test, new MyAdvice());[/align]
[align=left] list.add(123);[/align]
[align=left] list.add(123);[/align]
[align=left] System. out.println(list);[/align]
[align=left] }[/align]
public staticObject
getProxy(finalObject target, final Advice
adv)/* 终态是因为内部类调用 */ {
//
返回一个指定接口的代理类实例 obj
[align=left] Object obj = Proxy. newProxyInstance([/align]
//
定义代理类的类加载器
[align=left] target.getClass().getClassLoader(),[/align]
//
代理类要实现的接口列表
[align=left] target.getClass().getInterfaces(),[/align]
//
指派方法调用的调用处理程序 InvocationHandler
new InvocationHandler()
{
[align=left] @Override[/align]
publicObject
invoke(Object proxy, Method method,
Object[] args) throws Throwable
{
[align=left] adv.begintime(method);[/align]
//target目标
,args方法参数,调用原来的方法
[align=left] Object retVal = method.invoke(target, args);[/align]
[align=left] adv.endtime(method);[/align]
[align=left] return retVal;[/align]
[align=left] }[/align]
[align=left] });[/align]
[align=left] return obj;[/align]
[align=left] }[/align]
[align=left]}[/align]
[align=left]//插入的建议接口[/align]
interface Advice
{
void begintime(Method
method);
void endtime(Method
method);
[align=left]}[/align]
[align=left]//我的建议[/align]
class MyAdvice implements Advice
{
[align=left] @Override[/align]
public void begintime(Method
method) {
[align=left] Long time = System. currentTimeMillis();[/align]
System. out.println(method.getName()
+ time);
[align=left] }[/align]
[align=left] @Override[/align]
public void endtime(Method
method) {
[align=left] Long time = System. currentTimeMillis();[/align]
System. out.println(method.getName()
+ time);
[align=left] }[/align]
[align=left]}[/align]
一个更巧妙的方法:自定义一个处理程序
public class Ts
{
public static void main(String[]
args) throws Exception {
[align=left] ProxyHandler handler= new ProxyHandler();[/align]
[align=left] ClothingProduct cp2=(ClothingProduct)handler.newProxyInstance( new LiNingCompany());[/align]
[align=left] cp2.productClothing();[/align]
[align=left] }[/align]
[align=left]}[/align]
class ProxyHandler implements InvocationHandler
{
/*
目标对象 */
[align=left] privateObject target ;[/align]
/*
创建目标对象的代理对象 */
publicObject
newProxyInstance(Object target) {
this.target =
target;
[align=left] /*[/align]
[align=left] * 第一个参数:定义代理类的类加载器[/align]
[align=left] * 第二个参数:代理类要实现的接口 列表[/align]
[align=left] * 第三个参数:指派方法调用的调用处理程序[/align]
[align=left] */[/align]
[align=left] return Proxy.newProxyInstance(this. target.getClass().getClassLoader(),[/align]
[align=left] this.target .getClass().getClasses(), this);[/align]
[align=left] }[/align]
[align=left] @Override[/align]
publicObject
invoke(Object proxy, Method method,Object[] args)
throws Throwable
{
[align=left] Object result = null;[/align]
[align=left] System. out.println("目标对象上的方法调用之前可以添加其他代码。。。" );[/align]
result = method.invoke( this.target ,
args); // 通过反射调用目标对象上的方法
[align=left] System. out.println("目标对象上的方法调用之后可以添加其他代码。。。" );[/align]
[align=left] return result;[/align]
[align=left] }[/align]
[align=left]}[/align]
ASP.Net+Android+IO开发、.Net培训、期待与您交流!
相关文章推荐
- 黑马程序员:Java基础总结----静态代理模式&动态代理
- java设计模式之代理模式 (静态&动态)
- 黑马程序员__4java基础 静态和几种设计模式
- 黑马程序员——java基础知识篇——>异常总结
- 黑马程序员_java高新技术—类加载器&&动态代理
- Java基础加强总结之动态代理(Proxy)
- JAVA设计模式之代理模式(静态代理和动态代理)
- 【java项目实战】代理模式(Proxy Pattern),静态代理 VS 动态代理
- 黑马程序员:Java基础总结----装饰设计模式
- java的代理模式(静态和动态代理)
- Java之静态代理和动态代理模式
- 黑马程序员:Java基础总结----string类&stringbuffer
- java静态代理和动态代理(JDK&cglib)
- Java基础 - 类的加载,类加载器,反射,动态代理,模板设计模式,JDK5新特性,枚举(类),JDK1.7新特性
- Java 代理模式:静态代理、JDK 动态代理和 Cglib 动态代理的区别
- java设计模式--代理模式(静态代理和动态代理)
- JAVA中的静态代理、动态代理以及CGLIB动态代理总结
- Java设计模式——代理模式(静态代理vs动态代理)
- java设计模式之四:代理模式 java静态代理和动态代理
- 黑马程序员__JAVA基础加强--类加载器和代理总结