java——代理模式_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > java——代理模式

java——代理模式

 2013/12/12 16:09:08  lazyzhong  程序员俱乐部  我要评论(0)
  • 摘要:1、静态代理由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。接口类:packageorg.lazyzhong.test;publicinterfacePeople{publicvoidspeak();publicvoiddoWork();}实现类:packageorg.lazyzhong.test;publicclassManimplementsPeople{@Overridepublicvoidspeak(){System.out
  • 标签:Java 模式 代理 代理模式

1、静态代理

程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。

接口类:

package org.lazyzhong.test;

public interface People {
	public void speak();
	
	public void doWork();
}

?实现类:

package org.lazyzhong.test;

public class Man implements People{

	@Override
	public void speak() {
		System.out.println("I am man");
	}

	@Override
	public void doWork() {
		System.out.println("I do work");
	}
	
	
}

?代理类:

package org.lazyzhong.test;

public class PeopleProxy implements People{
	private Man man;
	
	public PeopleProxy() {
		super();
	}

	public PeopleProxy(Man man) {
		this.man = man;
	}

	@Override
	public void speak() {
		System.out.println("有请人类1/2的代表讲话。。。");
		man.speak();
		System.out.println("人类1/2的代表讲话完毕。。。");
	}

	@Override
	public void doWork() {
		
	}
	
	
}

?测试类:

		People p=new PeopleProxy(new Man());
		p.speak();

?输出:

有请人类1/2的代表讲话。。。
I am man
人类1/2的代表讲话完毕。。。

?

2、动态代理

在程序运行时,运用反射机制动态创建而成。

2.1 jdk动态代理

接口类,实现类和上面的一样。。。

代理类:

package org.lazyzhong.test;

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

public class MyProxy implements InvocationHandler{
	private Object target;
	
	public Object bind(Object target){
		this.target=target;
		return Proxy.newProxyInstance(target.getClass().getClassLoader(),  target.getClass().getInterfaces(),this);
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable { //方法中的Proxy不是target,是虚拟的实现类。
	      Object result=null;  
	      System.out.println("事物开始");  
	      result=method.invoke(target, args);  
	      System.out.println("事物结束");  
	      return result;  
	}

}

?测试类:

		MyProxy proxy=new MyProxy();
		People p=(People)proxy.bind(new Man());
		p.speak();
		p.doWork();		

?输出:

事物开始
I am man
事物结束
事物开始
I do work
事物结束

JDK动态代理中包含一个类和一个接口:?
InvocationHandler接口:?
public interface InvocationHandler {?
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;?
}?
参数说明:?
Object proxy:指被代理的对象。?
Method method:要调用的方法?
Object[] args:方法调用时所需要的参数?

可以将InvocationHandler接口的子类想象成一个代理的最终操作类,替换掉ProxySubject。?

Proxy类:?
Proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成实现类,此类提供了如下的操作方法:?
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)? throws IllegalArgumentException?
参数说明:?
ClassLoader loader:类加载器?
Class<?>[] interfaces:得到全部的接口?
InvocationHandler h:得到InvocationHandler接口的子类实例

?

2.2 cglib动态代理:注意cglib是否和asm.jar版本冲突..这里用的是cglib-2.1.95和asm-3.3

实现类:

package org.lazyzhong.test;

public class Man{ //注意并没有实现接口

	public void speak() {
		System.out.println("I am man");
	}
	
}

?代理类:

package org.lazyzhong.test;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class MyCGProxy implements MethodInterceptor{

	private Object target;
	
	/**
	 *	创建代理对象 
	 * @param target
	 * @return
	 */
	public Object getInstance(Object target){
		this.target=target;
        Enhancer enhancer = new Enhancer();  
        enhancer.setSuperclass(this.target.getClass());  
        // 回调方法  
        enhancer.setCallback(this);  
        // 创建代理对象  
        return enhancer.create();  
	}
	
	@Override
	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
	      System.out.println("事物开始");  
	      proxy.invokeSuper(obj, args);  
	      System.out.println("事物结束");  
	      return null;
	}

}

?测试:

		MyCGProxy pro=new MyCGProxy();
		Man man=(Man)pro.getInstance(new Man());
		man.speak();

?输出:

事物开始
I am man
事物结束

JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。

?

发表评论
用户名: 匿名