代理

用代码来简单看看代理模式

有个类

class A{

 void sayHello(){

     System.out.println("we like ZhangXiaoXiang teacher");----------------------位置1

 }

}

现在我想在位置1的代码打印输出前或后,打印点其他的比如System.out.println("we like HeiMaXuenLianYing!");,但是这时候我没有源文件(.java文件)改不了源码,我只能调用A类中的sayHello方法,那怎么办呢?

这时候我们就可以用代理模式带实现这一需求,重新定义一个类(A对象的代理类)

package shipin49;

/**
 * A类的代理
 *
 * @author Terry
 * @date 2014-5-29
 *
 */
public class AProxy {
 public void sayHello(){
  A a = new A();
  //附加的代码
  System.out.println("we like HeiMaXuenLianYing1!");
  a.sayHello();
  System.out.println("we like HeiMaXuenLianYing2!");
 }
}

在main方法中运行如下代码

public static void main(String[] args) {
  // TODO Auto-generated method stub
  //客户端不直接找被代理的对象(厂家),而是找代理商
  AProxy aproxy = new AProxy();
  aproxy.sayHello();
  //直接找厂家失去了代理意义
  System.out.println("--------------------------------");
  A a = new A();
  a.sayHello();
 }

输出结果

we like HeiMaXuenLianYing1!
we like ZhangXiaoXiang teacher
we like HeiMaXuenLianYing2!
--------------------------------
we like ZhangXiaoXiang teacher

感觉代理模式和装饰者模式很相像。装饰者模式重点在于添加附加行为修饰被装饰者,而代理模式的重点则是代替本人作业,减少对实际对象的操作。

AOP(面向切面编程)

什么是AOP?

1、AOP

      Aspect(方面 )Oriented(导向)Programming(程序设计):意为:面向切面(行为)编程,通过预编译方式和运行期动态代理来实现程序功能的统一维护的一种技术。是函数式编程的一种衍生泛型。AOP在其他领域有其他含义。它是Spring框架中的一个重要内容。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。[1]

2、函数式编程(直白的说函数式编程就是方法编程----这是我的理解)   

      函数式编程是种编程典范,它将电脑运算视为函数的计算。函数编程语言最重要的基础是 λ 演算(lambda calculus)。而且λ演算的函数可以接受函数当作输入(参数)和输出(返回值)。和指令式编程相比,函数式编程强调函数的计算比指令的执行重要。和过程化编程相比,函数式编程里,函数的计算可随时调用。

3、更加详细的AOP参照http://baike.baidu.com/subview/73626/13548606.htm?fr=aladdin(百度百科)

张孝祥老师视频中的AOP解说

   ●系统中存在着许多交叉业务,一个交叉业务就是要切入到系统中的一个方面,如下所示

                                                              安全                       事物                          日志

      StudentService-----------------------------|------------------------|--------------------------|-----------------------------

      管理学生信息的类(管理学生模块)  |                             |                               |

      CourseService------------------------------|------------------------|--------------------------|-----------------------------

      管理课程信息的类 (管理课程模块) |                             |                               |

      ClassroomService--------------------------|------------------------|------------------------- |-----------------------------

      管理教室信息的类(管理教室模块)

    上面的这3个类,他们各管各的事,互不往来,但是他们都要有安全,都要处理事物,都要写日志,而安全、事物、日志都贯穿到了许多个模块当中,于是这3个功能就成了模块的交叉业务  。它们就是交叉业务,穿插到了许多的类当中。

   ●用具体的程序代码描述交叉业务:

     method1  (模块1)                     method2 (模块2)                            method3(模块3)

     {                                                    {                                                           { 

     -------------------------------------------------------------------------------------------------------切面 (在方法的这个位置,都要他们有日志功能或安全功能亦或其他的功能)

     .............                                        ..............                                              ............                    

     -------------------------------------------------------------------------------------------------------切面                                                                                                              

     }                                                    }                                                           }          

    ●交叉业务的编程问题即为面向方面的编程,AOP的目标就是要使交叉业务模块化。可以采用将切面代码移动到原始方法的周围,这与直接在方法中编写切面代码的运行效果是一样的,如下所示:

    -------------------------------------------------------------------------------------------------------切面 (在方法的这个位置,都要他们有日志功能或安全功能亦或其他的功能)

    method1  (模块1)                     method2 (模块2)                              method3(模块3)

     {                                                    {                                                           { 

     .............                                        ..............                                              ............                    

     }                                                    }                                                           }            

     -------------------------------------------------------------------------------------------------------切面 (在方法的这个位置,都要他们有日志功能或安全功能亦或其他的功能)

     ●使用代理技术正好可以解决这种问题,代理是实现AOP功能的核心和关键技术。

动态代理技术

1、

要为系统中的各种接口增加代理功能,如果用静态代理,那将需要再增加和系统中的接口一样多的代理类,那样工程量很大,也太麻烦。

JVM可以在运行期动态生成出类的字节码,这种动态生成的类往往被用做代理,既动态代理。

JVM生成的动态类必须实现一个或多个接口,所以,JVM生成的动态类只能用作具有相同接口的目标类代理。(如果不实现一个或多个接口,那JVM生成的动态类就没有方法,一个没有方法的类那来做什么呢?这样意义不大。)

如果有一个类它没有实现任何接口,那此时要动态的生成此类的代理,但是JVM生成的又必须要实现一个或多个接口,这时候怎么办呢?可以使用第三方的CGLIB库来动态生成此类的代理。

代理的内容可以放在目标方法的什么位置呢?

    void proxyMothod(){

            位置1----------------在调用目标方法之前

            try{

                 targetMothod();

            }catch(Exception e){

            位置2-----------------在调用目标方法异常的cath语句中

            }

             位置3----------------在调用目标方法之后

    }

打印动态代理生成的字节码中的方法

 public static void main(String[] args) {
  // TODO Auto-generated method stub
  //一般情况下类加载器都是用和接口一样的,但是你可以用其他的类加载器类,clazzProxy1动态代理加载的类
  Class clazzProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
  System.out.println("字节码名字:"+clazzProxy1.getName());
  //获得动态代理生成的类的构造方法
  Constructor[] constructors = clazzProxy1.getConstructors();
  for (Constructor constructor : constructors) {
   StringBuilder sb = new StringBuilder();
   sb.append("构造方法:"+constructor.getName()+"(");
   for (Class clazz : constructor.getParameterTypes()) {
    sb.append(clazz.getName().substring(clazz.getName().lastIndexOf(".")+1)+",");
   }
   sb.deleteCharAt(sb.lastIndexOf(","));
   sb.append(");");
   System.out.println(sb);
  }
  /**
   * 打印其他方法
   */
  for (Method constructor : clazzProxy1.getMethods()) {
   StringBuilder sb = new StringBuilder();
   sb.append("其他方法:"+constructor.getName()+"(");
   for (Class clazz : constructor.getParameterTypes()) {
    sb.append(clazz.getName().substring(clazz.getName().lastIndexOf(".")+1)+",");
   }
   if(sb.lastIndexOf(",")!=-1){
    sb.deleteCharAt(sb.lastIndexOf(","));
   }
   sb.append(");");
   System.out.println(sb);
  }
 }

运行输出:

$Proxy0
构造方法:$Proxy0(InvocationHandler);
其他方法:add(Object);
其他方法:equals(Object);
其他方法:toString();
..........

2、创建动态类的实例对象

问题一:

public static void main(String[] args) throws Exception {

Class clazz = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
          clazz.newInstance();
}

上面的代码可以运行吗?

答:不可以,因为clazz没有无参的构造函数方法。

示例代码:

/**
   * 内部类
   * Invocation(调用)Handler(处理程序)
   * @author Terry
   * @date 2014-5-29
   *
   */
  class MyInvocationHander1 implements InvocationHandler{

   @Override
   public Object invoke(Object proxy, Method method, Object[] args)
     throws Throwable {
    // TODO Auto-generated method stub
    return null;-------------------------------------------------------------------------3
   }
   
  }
  //获得动态代理的字节码,Collection是个接口
  Class clazz = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
  //获得构造函数,不能使用clazz.newInstance()因为clazz没有无参的构造函数
  Constructor con = clazz.getConstructor(InvocationHandler.class);
  //用构造函数创建一个新的对象new MyInvocationHander1()自定义的InvocationHandler
  Collection collection = (Collection)con.newInstance(new MyInvocationHander1());
  Collection test = null;
  System.out.println(collection);//这里的结果为空,但是有2中情况,一种是对象为空,一种是toString()的返回值为空
  System.out.println(test);
//  System.out.println(collection.toString());-------------------------------------1
//  System.out.println(test.toString());---------------------------------------------2

在main方法中运行输出:

null
null

将位置1的代码取消注释运行输出:

null
null
null

将位置2的代码取消注释运行报空指针异常

注销位置2的代码,更改位置3的代码为:return "wahaha";运行输出:

wahaha
null
wahaha

判断对象是否为空System.out.println(collection==null);运行输出:false;

匿名内部类的写法:

//new InvocationHandler();new InvocationHandler(){},大括号的意义,不是很懂
  Collection collection2 = (Collection)con.newInstance(new InvocationHandler(){
   @Override
   public Object invoke(Object proxy, Method method, Object[] args)
     throws Throwable {
    // TODO Auto-generated method stub
    return null;
   }
   
 });

Proxy另一种newProxyInstance方法

static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
          返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。

这方法和上面的示例代码的效果是一样的。

方法一、

public void dynamicProxy(){
  Object object = Proxy.newProxyInstance(System.class.getClassLoader(), new Class[]{Collection.class}, new InvocationHandler() {
   
   @Override
   public Object invoke(Object proxy, Method method, Object[] args)
     throws Throwable {
    // TODO Auto-generated method stub
    return null;
   }
  });  
  printMethodName(object.getClass());
 }

方法二、
 /**
  * 打印一个类中的所有方法
  * @param clazz1
  */
 public static void printMethodName(Class clazz1){
  for (Method constructor : clazz1.getMethods()) {
   StringBuilder sb = new StringBuilder();
   sb.append("其他方法:"+constructor.getName()+"(");
   for (Class clazz : constructor.getParameterTypes()) {
    sb.append(clazz.getName().substring(clazz.getName().lastIndexOf(".")+1)+",");
   }
   if(sb.lastIndexOf(",")!=-1){
    sb.deleteCharAt(sb.lastIndexOf(","));
   }
   sb.append(");");
   System.out.println(sb);
  }
 }

方法三、

在main方法中调用:

ProxyTest pt = new ProxyTest();
  pt.dynamicProxy();

运行输出:

其他方法:add(Object);
其他方法:equals(Object);
其他方法:toString();
其他方法:hashCode();
其他方法:clear();

...............

问题二、Object object = Proxy.newProxyInstance(System.class.getClassLoader(),
new Class[]{Collection.class,Date.class}, new InvocationHandler()...将代码改成这个程序报错,原因仔细看了帮助文档后明白了。

示例代码:

public void dynamicProxy(){
  Collection collectionProxy = (Collection)Proxy.newProxyInstance(
    System.class.getClassLoader(),
    new Class[]{Runnable.class,Comparable.class,Collection.class},
    new InvocationHandler() {
    ArrayList target = new ArrayList();//被代理的对象,Collection间接的实现类
   @Override
   /**
    *
    * @param proxy:代理对象(JVM动态生成的)
    * @param method:被调用的方法
    * @param args:方法中的参数

    * @return :返回方法的返回值
    */
   public Object invoke(Object proxy, Method method, Object[] args)
     throws Throwable {
    // TODO Auto-generated method stub
    System.out.println("=====================================================");
//    ArrayList target = new ArrayList();//被代理的对象,Collection间接的实现类
//    System.out.println(proxy);
    System.out.println(method.getName());
    if(args!=null){
     for (Object object : args) {
      System.out.println(object);
     }
    }   
    //在调用目标之前做点什么
    System.out.println("附加的内容1");
    Object objct = method.invoke(target, args);
    //在调用目标之后做点什
    System.out.println("附加的内容2");
    return objct;
   }
  });
//  System.out.println(object);
//  printMethodName(object.getClass());
  collectionProxy.add("zxx");
  collectionProxy.add("lhm");
  collectionProxy.remove("lhm");
  collectionProxy.add(new ArrayList().add(new ArrayList().add("hahahaha")));-----------------------------------这里输出true的原因是,方法添加成功所以为true
  System.out.println("大小是多少:" + collectionProxy.size());
 }

在main方法中运行:

ProxyTest pt = new ProxyTest();
  pt.dynamicProxy();输出结果:

=====================================================
add
zxx
附加的内容1
附加的内容2
=====================================================
add
lhm
附加的内容1
附加的内容2
=====================================================
remove
lhm
附加的内容1
附加的内容2
=====================================================
add
true
附加的内容1
附加的内容2
=====================================================
size
附加的内容1
附加的内容2
大小是多少:2

自己写的一个小型的通用性动态代理框架

接口

/**
 * 功能程序的接口
 *
 * @author Terry
 * @date 2014-5-30
 *
 */
public interface Advice {
 public void before();
 public void laster();
}

接口的实现类

类1

/**
 * 功能程序1
 *
 * @author Terry
 * @date 2014-5-30
 *
 */
public class MyAdvice1 implements Advice {

 @Override
 public void before() {
  // TODO Auto-generated method stub
  System.out.println("MyAdvice1开始");
 }

 @Override
 public void laster() {
  // TODO Auto-generated method stub
  System.out.println("MyAdvice1结束");
 }

}

类2

/**
 * 功能程序2
 *
 * @author Terry
 * @date 2014-5-30
 *
 */
public class MyAdvice2 implements Advice {

 @Override
 public void before() {
  // TODO Auto-generated method stub
  System.out.println("MyAdvice2开始");
 }

 @Override
 public void laster() {
  // TODO Auto-generated method stub
  System.out.println("MyAdvice2结束");
 }

}

通用性动态代理框架

/**
  * 自己写的一个小型的通用性动态代理框架
  * @param target:被代理的目标类
  * @param advice:忠告,建议的意思。这里是代理目标方法调所附加的代码。(安全、事务、日志等)
  * @return 返回目标方法返回的结果
  */
 private static Object getProxy(final Object target,final Advice advice) {
  Object proxy = (Object)Proxy.newProxyInstance(
    System.class.getClassLoader(),
    target.getClass().getInterfaces(), 
     new  InvocationHandler() {
     @Override
     public Object invoke(Object proxy, Method method, Object[] args)
       throws Throwable {
      // TODO Auto-generated method stub
      advice.before();
      System.out.println("方法:"+method.getName()+":参数"+args[0]);
      Object object1 = method.invoke(target, args);
      advice.laster();
      return object1;
     }
    });
  return proxy;
 }

在main方法中运行如下代码:

Collection proxy1 =  (Collection)getProxy(new ArrayList(),new MyAdvice1()); 
  Serializable proxy3 =  (Serializable)getProxy(new ArrayList(),new MyAdvice1());//proxy1,proxy3为什么对的?Serializable和Collection是ArrayList的接口
  //ArrayList proxy4 =   (ArrayList)getProxy(new ArrayList(),new MyAdvice1());//错误为什么?

  //System.out.println(proxy1.getClass());输出打印:class $Proxy0,由此可以知道getProxy方法返回的是一个JVM动态生成的代理类,而此类继承了Serializable和Collection接口,在上面的框架方法中target.getClass().getInterfaces(), 有所体现,但是此类没有继承ArrayList,因为JVM动态生成的代理类必须继承接口。

proxy3.equals("22");
  System.out.println(proxy1.getClass());
  proxy1.add("zxx");
  proxy1.equals("333");
  Runnable proxy2 = (Runnable) getProxy(new Thread(),new MyAdvice2());
  proxy2.equals("aaa");

运行输出:

MyAdvice1开始
方法:equals:参数22
MyAdvice1结束
class $Proxy0
MyAdvice1开始
方法:add:参数zxx
MyAdvice1结束
MyAdvice1开始
方法:equals:参数333
MyAdvice1结束
MyAdvice2开始
方法:equals:参数aaa
MyAdvice2结束

模拟Sptring框架(Spring的两大核心Bean工厂和AOP框架)

类1、

package shipin56;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import shipin49.Advice;
/**
 * Java,BeanFactory工厂类:用来创建动态代理
 * 这里与之相关的应该是简单工厂设计模式吧
 * @author Terry
 * @date 2014-5-30
 *
 */
public class BeanFactory {
	Properties props = new Properties();
	/**
	 * 将xml文件以流的方式传进来
	 * @param ips,键值对的流
	 */
	public BeanFactory(InputStream ips){
		try {
			props.load(ips);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//做商业性项目要做异常处理
			e.printStackTrace();
		}
	}

	/**
	 * 获得Bean对象,如果找到的类是ProxyFactoryBean类型的,这返回此代理工厂生产的代理类JavaBean
	 * @param name,在xml中键值对的key值
	 * @return JavaBean
	 */
	public Object getBean(String name){
		//获取xml中,key键为name的值
		String className = props.getProperty(name);
		Object bean = null;
		try {
			Class clazz = Class.forName(className);
			bean = clazz.newInstance();
			//如果获得的bean对象是ProxyFactoryBean代理工厂类型的
			if (bean instanceof ProxyFactoryBean){
				ProxyFactoryBean pfb = (ProxyFactoryBean) bean;
				Advice advice = (Advice) Class.forName(props.getProperty(name+".advice")).newInstance();
				Object target = Class.forName(props.getProperty(name+".target")).newInstance();
				//设置切面对象(安全、事务、日志)
				pfb.setAdvice(advice);
				//设置被代理的目标
				pfb.setTarget(target);
				Object proxy = pfb.getProxy();
				//返回代理对象
				return proxy;
			}
		} catch (Exception e) {

		}
		//返回其他对象
		return bean;
	}
}

类2

package shipin56;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import shipin49.Advice;

/**
 * 在Spring中,这里用的是接口,为了灵活吧
 * 代理工厂类
 * @author Terry
 * @date 2014-5-30
 *
 */
public class ProxyFactoryBean {

	/**
	 * 获得代理对象
	 * @return 代理对象
	 */
	public Object getProxy() {
		Object proxy = (Object)Proxy.newProxyInstance(
				//用被代理类的类加载器加载动态对象
				target.getClass().getClassLoader(),
				//为代理类指定接口
				target.getClass().getInterfaces(),
				new InvocationHandler() {
					@Override
					/**
					 *
					 */
					public Object invoke(Object proxy, Method method, Object[] args)
							throws Throwable {
						// TODO Auto-generated method stub
						advice.before();
						System.out.println("我在InvocationHandler类中的invoke()方法中:"+proxy.getClass().getName());
						System.out.println("代理:"+proxy.getClass().getName()+"方法:"+method.getName()+":参数"+args[0]);
						Object object1 = method.invoke(target, args);
						advice.laster();
						return object1;
					}
				});
		return proxy;
	}

	//目标类
	private Object target;
	//切面对象
	private Advice advice;
	public Object getTarget() {
		return target;
	}
	public void setTarget(Object target) {
		this.target = target;
	}
	public Advice getAdvice() {
		return advice;
	}
	public void setAdvice(Advice advice) {
		this.advice = advice;
	}

}

类3:main方法

package shipin56;

import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;

public class Main {

	/**
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		InputStream ips = Main.class.getResourceAsStream("config.properties");
		Object bean = new BeanFactory(ips).getBean("xxx");
		Collection col = (Collection)bean;
		col.add("aaa");

	}
}

接口类

package shipin49;
/**
 * 功能程序的接口
 *
 * @author Terry
 * @date 2014-5-30
 *
 */
public interface Advice {
	public void before();
	public void laster();
}

实现类1

package shipin49;

/**
 * 功能程序1
 *
 * @author Terry
 * @date 2014-5-30
 *
 */
public class MyAdvice1 implements Advice {

	@Override
	public void before() {
		// TODO Auto-generated method stub
		System.out.println("MyAdvice1开始");
	}

	@Override
	public void laster() {
		// TODO Auto-generated method stub
		System.out.println("MyAdvice1结束");
	}

}

实现类2

package shipin49;

/**
 * 功能程序2
 *
 * @author Terry
 * @date 2014-5-30
 *
 */
public class MyAdvice2 implements Advice {

	@Override
	public void before() {
		// TODO Auto-generated method stub
		System.out.println("MyAdvice2开始");
	}

	@Override
	public void laster() {
		// TODO Auto-generated method stub
		System.out.println("MyAdvice2结束");
	}

}

XML配置,XML文件取名config.properties

#xxx=java.util.ArrayList
xxx=shipin56.ProxyFactoryBean
xxx.advice=shipin49.MyAdvice1
xxx.target=java.util.ArrayList

运行程序输出结果:

MyAdvice1开始
我在InvocationHandler类中的invoke()方法中:$Proxy0
代理:$Proxy0方法:add:参数aaa
MyAdvice1结束

将XML里面的配置中的xxx.advice的值改为xxx.advice=shipin49.MyAdvice2运行输出:

MyAdvice2开始
我在InvocationHandler类中的invoke()方法中:$Proxy0
代理:$Proxy0方法:add:参数aaa
MyAdvice2结束

知识点:

Proxy类

static Class<?> getProxyClass(ClassLoader loader,Class<?>... interfaces)
          返回代理类的 java.lang.Class 对象,并向其提供类加载器和接口数组。
static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
          返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。

Invocation(调用)Handler(处理程序)类

Object invoke(Object proxy,Method method,Object[] args)
          在代理实例上处理方法调用并返回结果。

Properties类

 void load(InputStream inStream)
          从输入流中读取属性列表(键和元素对)。

Class类

 URL getResource(String name)
          查找带有给定名称的资源。

23中常用的设计模式之-----------------------红酒经销:代理模式











时间: 2024-09-13 12:11:43

代理的相关文章

大话设计模式之代理模式

代理模式的应用场合: 一,远程代理 二,虚拟代理 三,安全代理 简单来说,就是两个类共同实现接口,一个实现,一个调用这个实现.而调用实现的类,就是代理类. 针对书上的代码,我加了一个NAME变量和一个SHOWNAME方法.更加直观展示代理的细节. 1 /* 2 * Created by SharpDevelop. 3 * User: home 4 * Date: 2013/4/21 5 * Time: 9:33 6 * 7 * To change this template use Tools

ip-《TCP/IP 详解卷一》中90页中讲到,“由于子网号不相同,代理ARP不能使用”,这怎么理解?

问题描述 <TCP/IP 详解卷一>中90页中讲到,"由于子网号不相同,代理ARP不能使用",这怎么理解? <TCP/IP 详解卷一>中90页中讲到,"由于子网号不相同,代理ARP不能使用",这怎么理解? 解决方案 ARP主要用在一个子网中,用MAC地址来通信.数据链路层 不同子网,需要通过三层路由 解决方案二: 比如 N1 <-> GW <-> N2,N1和N2是同一个子网,GW上开启arp代理的效果是,N1和N2上

iOS UITableView代理方法详解

IOS UITableView的代理方法详解 一.补充 在上一篇博客中,http://my.oschina.net/u/2340880/blog/404605,我将IOS中tableView(表视图)的一些常用方法总结了一下,这篇将tableView的代理方法作了总结,对上一篇博客进行了补充. 二.UITableViewDataSourc(数据源代理) 1.必须实现的回调方法 返回每个分区的行数 - (NSInteger)tableView:(UITableView *)tableView nu

快速可扩展的Ajax流代理——提供持续下载跨域数据

简介 由于浏览器禁止跨域的XMLHTTP调用,所有的Ajax网站都必须有一个服务端代理来从外部域比如Flickr或者Digg来抓去内容.对客户端Javascript代码来说,一个XMLHttp的调用将请求传递给宿主在相同域里的服务端代理,然后由代理来从外部服务器上下载内容,并回传给客户端.通常,所有从外部服务器获取内容的Ajax站点都采用这种代理方案,除了一些罕见的使用JSONP的人.当网站上的许多组件正在从外部域下载内容时,这样的代理将会被大量地调用.所以,当代理开始被百万次地调用时,它将变成

JAVA核心层--反射--动态代理

本文发表于2010年,时间较早,部分问题解释不是十分准确,所以需要进一步了解,请参看2012年版本: java之架构基础-动态代理&cglib 要在JAVA技术上突破普通的层面,并拥有一翻设计理念的高度,除了要有很好的设计思维之外,反射在适当的使用下,将会把框架做得非常清晰,并且代码编写也非常简便. 在面向对象的编程中,我们为什么要忌讳去大量使用if else switch语句,因为这样写是将逻辑硬编码了,JAVA的思想就是将其配置化,一旦可配置化后,就逐渐可管理化,并随着产品的成熟逐步实现自动

java之架构基础-动态代理&amp;amp;cglib

本文核心主要参数动态代理和cglib: 在以前的文章中,有提及到动态代理,它要解决的就是,当我们的某些代码前面或后面都需要一些处理的时候,如写日志.事务控制.做agent.自动化代码跟踪等,此时会给你带来无限的方便,这是JVM级别的提供的一种代理机制,不过在这种机制下调用方法在JVM7出来前还没有invokeDynamic的时候,调用的效率是很低的,此时方法调用都是通过method的invoke去实现. 其基本原理是基于实现JVM提供的一个: InvocationHandler的接口,实现一个方

你真的了解iOS代理设计模式吗?

本文是投稿文章,作者:刘小壮 在项目中我们经常会用到代理的设计模式,这是iOS中一种消息传递的方式,也可以通过这种方式来传递一些参数.这篇文章会涵盖代理的使用技巧和原理,以及代理的内存管理等方面的知识.我会通过这些方面的知识,带大家真正领略代理的奥妙.写的有点多,但都是干货,我能写下去,不知道你有没有耐心看下去.本人能力有限,如果文章中有什么问题或没有讲到的点,请帮忙指出,十分感谢! iOS中消息传递方式 在iOS中有很多种消息传递方式,这里先简单介绍一下各种消息传递方式. 通知:在iOS中由通

JDK和CGLIB生成动态代理类的区别

 关于动态代理和静态代理 当一个对象(客户端)不能或者不想直接引用另一个对象(目标对象),这时可以应用代理模式在这两者之间构建一个桥梁--代理对象. 按照代理对象的创建时期不同,可以分为两种: 静态代理:事先写好代理对象类,在程序发布前就已经存在了: 动态代理:应用程序发布后,通过动态创建代理对象. 静态代理其实就是一个典型的代理模式实现,在代理类中包装一个被代理对象,然后影响被代理对象的行为,比较简单,代码就不放了. 其中动态代理又可分为:JDK动态代理和CGLIB代理. 1.JDK动态代理

使用 ssh -R 建立反向/远程TCP端口转发代理

ssh是一个非常棒的工具, 不但能建立动态转发, 例如chrome的Switchy插件用到的就是这个技术. http://blog.163.com/digoal@126/blog/static/163877040201141821810103/ 还能建立TCP的转发隧道, 例如我以前写过的关于使用ssh 隧道加密和加速WAN传输的几个例子. http://blog.163.com/digoal@126/blog/static/163877040201342383123592/ http://bl

Http 代理工具 实战 支持网页与QQ代理

        private void CloseSocket(Socket socket)         {             CloseSocket(socket, true);         }         private void CloseSocket(Socket socket, bool shutdown)         {             if (socket != null)             {                 if (shut